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.
- _crosshair_tracers.cpython-312-darwin.so +0 -0
- crosshair/__init__.py +42 -0
- crosshair/__main__.py +8 -0
- crosshair/_mark_stacks.h +790 -0
- crosshair/_preliminaries_test.py +18 -0
- crosshair/_tracers.h +94 -0
- crosshair/_tracers_pycompat.h +522 -0
- crosshair/_tracers_test.py +138 -0
- crosshair/abcstring.py +245 -0
- crosshair/auditwall.py +190 -0
- crosshair/auditwall_test.py +77 -0
- crosshair/codeconfig.py +113 -0
- crosshair/codeconfig_test.py +117 -0
- crosshair/condition_parser.py +1237 -0
- crosshair/condition_parser_test.py +497 -0
- crosshair/conftest.py +30 -0
- crosshair/copyext.py +155 -0
- crosshair/copyext_test.py +84 -0
- crosshair/core.py +1763 -0
- crosshair/core_and_libs.py +149 -0
- crosshair/core_regestered_types_test.py +82 -0
- crosshair/core_test.py +1316 -0
- crosshair/diff_behavior.py +314 -0
- crosshair/diff_behavior_test.py +261 -0
- crosshair/dynamic_typing.py +346 -0
- crosshair/dynamic_typing_test.py +210 -0
- crosshair/enforce.py +282 -0
- crosshair/enforce_test.py +182 -0
- crosshair/examples/PEP316/__init__.py +1 -0
- crosshair/examples/PEP316/bugs_detected/__init__.py +0 -0
- crosshair/examples/PEP316/bugs_detected/getattr_magic.py +16 -0
- crosshair/examples/PEP316/bugs_detected/hash_consistent_with_equals.py +31 -0
- crosshair/examples/PEP316/bugs_detected/shopping_cart.py +24 -0
- crosshair/examples/PEP316/bugs_detected/showcase.py +39 -0
- crosshair/examples/PEP316/correct_code/__init__.py +0 -0
- crosshair/examples/PEP316/correct_code/arith.py +60 -0
- crosshair/examples/PEP316/correct_code/chess.py +77 -0
- crosshair/examples/PEP316/correct_code/nesting_inference.py +17 -0
- crosshair/examples/PEP316/correct_code/numpy_examples.py +132 -0
- crosshair/examples/PEP316/correct_code/rolling_average.py +35 -0
- crosshair/examples/PEP316/correct_code/showcase.py +104 -0
- crosshair/examples/__init__.py +0 -0
- crosshair/examples/check_examples_test.py +146 -0
- crosshair/examples/deal/__init__.py +1 -0
- crosshair/examples/icontract/__init__.py +1 -0
- crosshair/examples/icontract/bugs_detected/__init__.py +0 -0
- crosshair/examples/icontract/bugs_detected/showcase.py +41 -0
- crosshair/examples/icontract/bugs_detected/wrong_sign.py +8 -0
- crosshair/examples/icontract/correct_code/__init__.py +0 -0
- crosshair/examples/icontract/correct_code/arith.py +51 -0
- crosshair/examples/icontract/correct_code/showcase.py +94 -0
- crosshair/fnutil.py +391 -0
- crosshair/fnutil_test.py +75 -0
- crosshair/fuzz_core_test.py +516 -0
- crosshair/libimpl/__init__.py +0 -0
- crosshair/libimpl/arraylib.py +161 -0
- 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 +23 -0
- crosshair/libimpl/builtinslib.py +5228 -0
- crosshair/libimpl/builtinslib_ch_test.py +1191 -0
- crosshair/libimpl/builtinslib_test.py +3735 -0
- crosshair/libimpl/codecslib.py +86 -0
- crosshair/libimpl/codecslib_test.py +86 -0
- crosshair/libimpl/collectionslib.py +264 -0
- crosshair/libimpl/collectionslib_ch_test.py +252 -0
- crosshair/libimpl/collectionslib_test.py +332 -0
- crosshair/libimpl/copylib.py +23 -0
- crosshair/libimpl/copylib_test.py +18 -0
- crosshair/libimpl/datetimelib.py +2559 -0
- crosshair/libimpl/datetimelib_ch_test.py +354 -0
- crosshair/libimpl/datetimelib_test.py +112 -0
- crosshair/libimpl/decimallib.py +5257 -0
- crosshair/libimpl/decimallib_ch_test.py +78 -0
- crosshair/libimpl/decimallib_test.py +76 -0
- crosshair/libimpl/encodings/__init__.py +23 -0
- crosshair/libimpl/encodings/_encutil.py +187 -0
- crosshair/libimpl/encodings/ascii.py +44 -0
- crosshair/libimpl/encodings/latin_1.py +40 -0
- crosshair/libimpl/encodings/utf_8.py +93 -0
- crosshair/libimpl/encodings_ch_test.py +83 -0
- crosshair/libimpl/fractionlib.py +16 -0
- crosshair/libimpl/fractionlib_test.py +80 -0
- crosshair/libimpl/functoolslib.py +34 -0
- crosshair/libimpl/functoolslib_test.py +56 -0
- crosshair/libimpl/hashliblib.py +30 -0
- crosshair/libimpl/hashliblib_test.py +18 -0
- crosshair/libimpl/heapqlib.py +47 -0
- crosshair/libimpl/heapqlib_test.py +21 -0
- crosshair/libimpl/importliblib.py +18 -0
- crosshair/libimpl/importliblib_test.py +38 -0
- crosshair/libimpl/iolib.py +216 -0
- crosshair/libimpl/iolib_ch_test.py +128 -0
- crosshair/libimpl/iolib_test.py +19 -0
- crosshair/libimpl/ipaddresslib.py +8 -0
- crosshair/libimpl/itertoolslib.py +44 -0
- crosshair/libimpl/itertoolslib_test.py +44 -0
- crosshair/libimpl/jsonlib.py +984 -0
- crosshair/libimpl/jsonlib_ch_test.py +42 -0
- crosshair/libimpl/jsonlib_test.py +51 -0
- crosshair/libimpl/mathlib.py +179 -0
- crosshair/libimpl/mathlib_ch_test.py +44 -0
- crosshair/libimpl/mathlib_test.py +67 -0
- crosshair/libimpl/oslib.py +7 -0
- crosshair/libimpl/pathliblib_test.py +10 -0
- crosshair/libimpl/randomlib.py +178 -0
- crosshair/libimpl/randomlib_test.py +120 -0
- crosshair/libimpl/relib.py +846 -0
- crosshair/libimpl/relib_ch_test.py +169 -0
- crosshair/libimpl/relib_test.py +493 -0
- crosshair/libimpl/timelib.py +72 -0
- crosshair/libimpl/timelib_test.py +82 -0
- crosshair/libimpl/typeslib.py +15 -0
- crosshair/libimpl/typeslib_test.py +36 -0
- crosshair/libimpl/unicodedatalib.py +75 -0
- crosshair/libimpl/unicodedatalib_test.py +42 -0
- crosshair/libimpl/urlliblib.py +23 -0
- crosshair/libimpl/urlliblib_test.py +19 -0
- 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 +261 -0
- crosshair/lsp_server_test.py +30 -0
- crosshair/main.py +973 -0
- crosshair/main_test.py +543 -0
- crosshair/objectproxy.py +376 -0
- crosshair/objectproxy_test.py +41 -0
- crosshair/opcode_intercept.py +601 -0
- crosshair/opcode_intercept_test.py +304 -0
- crosshair/options.py +218 -0
- crosshair/options_test.py +10 -0
- crosshair/patch_equivalence_test.py +75 -0
- crosshair/path_cover.py +209 -0
- crosshair/path_cover_test.py +138 -0
- crosshair/path_search.py +161 -0
- crosshair/path_search_test.py +52 -0
- crosshair/pathing_oracle.py +271 -0
- crosshair/pathing_oracle_test.py +21 -0
- crosshair/pure_importer.py +27 -0
- crosshair/pure_importer_test.py +16 -0
- crosshair/py.typed +0 -0
- crosshair/register_contract.py +273 -0
- crosshair/register_contract_test.py +190 -0
- crosshair/simplestructs.py +1165 -0
- crosshair/simplestructs_test.py +283 -0
- crosshair/smtlib.py +24 -0
- crosshair/smtlib_test.py +14 -0
- crosshair/statespace.py +1199 -0
- crosshair/statespace_test.py +108 -0
- crosshair/stubs_parser.py +352 -0
- crosshair/stubs_parser_test.py +43 -0
- crosshair/test_util.py +329 -0
- crosshair/test_util_test.py +26 -0
- crosshair/tools/__init__.py +0 -0
- crosshair/tools/check_help_in_doc.py +264 -0
- crosshair/tools/check_init_and_setup_coincide.py +119 -0
- crosshair/tools/generate_demo_table.py +127 -0
- crosshair/tracers.py +544 -0
- crosshair/tracers_test.py +154 -0
- crosshair/type_repo.py +151 -0
- crosshair/unicode_categories.py +589 -0
- crosshair/unicode_categories_test.py +27 -0
- crosshair/util.py +741 -0
- crosshair/util_test.py +173 -0
- crosshair/watcher.py +307 -0
- crosshair/watcher_test.py +107 -0
- crosshair/z3util.py +76 -0
- crosshair/z3util_test.py +11 -0
- crosshair_tool-0.0.99.dist-info/METADATA +144 -0
- crosshair_tool-0.0.99.dist-info/RECORD +176 -0
- crosshair_tool-0.0.99.dist-info/WHEEL +6 -0
- crosshair_tool-0.0.99.dist-info/entry_points.txt +3 -0
- crosshair_tool-0.0.99.dist-info/licenses/LICENSE +93 -0
- crosshair_tool-0.0.99.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from crosshair.core import deep_realize, realize
|
|
7
|
+
from crosshair.simplestructs import (
|
|
8
|
+
LazySetCombination,
|
|
9
|
+
SequenceConcatenation,
|
|
10
|
+
ShellMutableMap,
|
|
11
|
+
ShellMutableSequence,
|
|
12
|
+
ShellMutableSet,
|
|
13
|
+
SimpleDict,
|
|
14
|
+
SingletonSet,
|
|
15
|
+
SliceView,
|
|
16
|
+
cut_slice,
|
|
17
|
+
operator,
|
|
18
|
+
)
|
|
19
|
+
from crosshair.test_util import summarize_execution
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_ShellMutableMap() -> None:
|
|
23
|
+
m = ShellMutableMap({4: 4, 5: 5, 6: 6})
|
|
24
|
+
m[3] = 3
|
|
25
|
+
m[4] = None
|
|
26
|
+
del m[5]
|
|
27
|
+
assert len(m) == 3
|
|
28
|
+
assert list(m) == [6, 3, 4]
|
|
29
|
+
assert m[4] is None
|
|
30
|
+
with pytest.raises(KeyError):
|
|
31
|
+
m[5]
|
|
32
|
+
assert m == {3: 3, 4: None, 6: 6}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_ShellMutableMap_popitem_ordering() -> None:
|
|
36
|
+
assert {"c": "d", "a": "b"}.popitem() == ("a", "b")
|
|
37
|
+
assert SimpleDict([("c", "d"), ("a", "b")]).popitem() == ("a", "b")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_ShellMutableMap_pop_with_default() -> None:
|
|
41
|
+
assert {"c": "d", "a": "b"}.popitem() == ("a", "b")
|
|
42
|
+
assert ShellMutableMap({}).pop("a", "x") == "x"
|
|
43
|
+
assert ShellMutableMap({"a": "b"}).pop("a", "x") == "b"
|
|
44
|
+
assert ShellMutableMap({"a": "b"}).pop("c", "x") == "x"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_ShellMutableMap_poo() -> None:
|
|
48
|
+
m = ShellMutableMap({2: 0})
|
|
49
|
+
assert 0 == m.setdefault(2.0, {True: "0"})
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_SequenceConcatenation_comparison() -> None:
|
|
53
|
+
compound = SequenceConcatenation((11, 22), (33, 44))
|
|
54
|
+
assert compound == (11, 22, 33, 44)
|
|
55
|
+
assert compound < (22, 33, 44)
|
|
56
|
+
assert compound >= (11, 22, 33) # type: ignore
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_SliceView_comparison() -> None:
|
|
60
|
+
sliced = SliceView((00, 11, 22, 33, 44, 55), 1, 5)
|
|
61
|
+
assert sliced == (11, 22, 33, 44)
|
|
62
|
+
assert sliced < (22, 33, 44)
|
|
63
|
+
assert sliced >= (11, 22, 33) # type: ignore
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_slice_view() -> None:
|
|
67
|
+
nums = ["0", "1", "2", "3", "4", "5"]
|
|
68
|
+
ctr = 0
|
|
69
|
+
for start in [0, 1, 2, 3, 4, 5, 6]:
|
|
70
|
+
for stop in range(start, 7):
|
|
71
|
+
view = SliceView(nums, start, stop)
|
|
72
|
+
concrete = nums[start:stop]
|
|
73
|
+
assert (
|
|
74
|
+
list(view) == concrete
|
|
75
|
+
), f"{ctr}: {start}:{stop}: {view} vs {concrete}"
|
|
76
|
+
if stop - start > 0:
|
|
77
|
+
assert view[0] == nums[start]
|
|
78
|
+
ctr += 1
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_LazySetCombination_xor() -> None:
|
|
82
|
+
a = {2, 4, 6}
|
|
83
|
+
b = {4, 5, 6, 7}
|
|
84
|
+
s = LazySetCombination(operator.xor, a, b)
|
|
85
|
+
assert s == {2, 5, 7}
|
|
86
|
+
assert 4 not in s
|
|
87
|
+
assert 5 in s
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_ShellMutableDict_realize() -> None:
|
|
91
|
+
shell = ShellMutableMap({1: ShellMutableMap({2: 3})})
|
|
92
|
+
realized = realize(shell)
|
|
93
|
+
assert isinstance(realized, dict)
|
|
94
|
+
assert isinstance(realized[1], ShellMutableMap)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_ShellMutableDict_deep_realize() -> None:
|
|
98
|
+
shell = ShellMutableMap({1: ShellMutableMap({2: 3})})
|
|
99
|
+
realized = deep_realize(shell)
|
|
100
|
+
assert isinstance(realized, dict)
|
|
101
|
+
assert isinstance(realized[1], dict)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def test_ShellMutableSet_deepcopy() -> None:
|
|
105
|
+
ls = ["0", "1", "2", "3"]
|
|
106
|
+
shell = ShellMutableSet(ls)
|
|
107
|
+
# deep_realize(shell)
|
|
108
|
+
copy.deepcopy(shell)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_ShellMutableSequence_slice_assignment() -> None:
|
|
112
|
+
ls = ["0", "1", "2", "3"]
|
|
113
|
+
shell = ShellMutableSequence(ls)
|
|
114
|
+
assert shell == shell
|
|
115
|
+
assert shell == ls
|
|
116
|
+
shell[1:3] = ["1", "1.5", "2"]
|
|
117
|
+
assert shell == ["0", "1", "1.5", "2", "3"]
|
|
118
|
+
assert shell == shell
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def test_ShellMutableSequence_assignment_negative_index() -> None:
|
|
122
|
+
ls = ShellMutableSequence(["a", "a"])
|
|
123
|
+
ls[-1] = "b"
|
|
124
|
+
assert ls == ["a", "b"]
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_ShellMutableSequence_assignment_bad_index() -> None:
|
|
128
|
+
with pytest.raises(TypeError):
|
|
129
|
+
ShellMutableSequence([])["whoa"] = 3
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def test_ShellMutableSequence_assignment_out_of_bounds() -> None:
|
|
133
|
+
with pytest.raises(IndexError):
|
|
134
|
+
ShellMutableSequence(["b", "c"])[-3] = "a"
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_ShellMutableSequence_sort_invalid_args() -> None:
|
|
138
|
+
s = ShellMutableSequence(SequenceConcatenation([], []))
|
|
139
|
+
if sys.version_info < (3, 12):
|
|
140
|
+
with pytest.raises(TypeError):
|
|
141
|
+
s.sort(reverse="badvalue")
|
|
142
|
+
else:
|
|
143
|
+
s.sort(reverse="badvalue") # no exception on 3.12
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def test_ShellMutableSequence_assignment_doesnt_pollute() -> None:
|
|
147
|
+
a = ShellMutableSequence([1, 2])
|
|
148
|
+
b = a + ShellMutableSequence([3, 4])
|
|
149
|
+
assert b == [1, 2, 3, 4]
|
|
150
|
+
a.append(3)
|
|
151
|
+
assert b == [1, 2, 3, 4]
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def test_ShellMutableSequence_assignment_doesnt_get_polluted() -> None:
|
|
155
|
+
a = [1, 2]
|
|
156
|
+
b = a + ShellMutableSequence([3, 4])
|
|
157
|
+
assert b == [1, 2, 3, 4]
|
|
158
|
+
a.append(3)
|
|
159
|
+
assert b == [1, 2, 3, 4]
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def test_SequenceConcatenation_operators() -> None:
|
|
163
|
+
s = SequenceConcatenation([4], [6]) + [8]
|
|
164
|
+
assert s == [4, 6, 8]
|
|
165
|
+
assert type(s) == SequenceConcatenation
|
|
166
|
+
s = [2] + SequenceConcatenation([4], [6])
|
|
167
|
+
assert s == [2, 4, 6]
|
|
168
|
+
assert type(s) == SequenceConcatenation
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def test_SingletonSet_arg_types() -> None:
|
|
172
|
+
s = SingletonSet(42)
|
|
173
|
+
with pytest.raises(TypeError):
|
|
174
|
+
s | [3, 5]
|
|
175
|
+
with pytest.raises(TypeError):
|
|
176
|
+
[3, 5] ^ s # type: ignore
|
|
177
|
+
with pytest.raises(TypeError):
|
|
178
|
+
s - [3, 5]
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def test_ShellMutableSet_members() -> None:
|
|
182
|
+
shell = ShellMutableSet([6, 4, 8, 2])
|
|
183
|
+
assert shell == shell
|
|
184
|
+
assert shell == {2, 4, 6, 8}
|
|
185
|
+
shell.pop()
|
|
186
|
+
assert list(shell) == [4, 8, 2]
|
|
187
|
+
shell.add(0)
|
|
188
|
+
assert list(shell) == [4, 8, 2, 0]
|
|
189
|
+
shell.clear()
|
|
190
|
+
assert list(shell) == []
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def test_ShellMutableSet_comparisons() -> None:
|
|
194
|
+
# Truths
|
|
195
|
+
assert ShellMutableSet([2, 4]) >= {2, 4}
|
|
196
|
+
assert ShellMutableSet([2, 4]) < {2, 3, 4}
|
|
197
|
+
assert ShellMutableSet([2, 4]) == {4, 2}
|
|
198
|
+
assert ShellMutableSet([2, 4]) != {}
|
|
199
|
+
assert ShellMutableSet([2, 4]).isdisjoint({1, 3, 5})
|
|
200
|
+
# Falsehoods
|
|
201
|
+
assert not (ShellMutableSet([2, 4]) > {2, 4})
|
|
202
|
+
assert not (ShellMutableSet([2, 4]) <= {4, 5})
|
|
203
|
+
assert not (ShellMutableSet([2, 4]).isdisjoint({1, 4, 5}))
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def test_ShellMutableSet_operators() -> None:
|
|
207
|
+
shell = ShellMutableSet([2, 4])
|
|
208
|
+
shell = shell | {6}
|
|
209
|
+
assert len(shell) == 3
|
|
210
|
+
assert list(shell) == [2, 4, 6]
|
|
211
|
+
shell = shell & {2, 6, 8}
|
|
212
|
+
assert list(shell) == [2, 6]
|
|
213
|
+
shell = shell ^ {0, 2, 4, 6}
|
|
214
|
+
assert list(shell) == [0, 4]
|
|
215
|
+
shell = shell - {0, 1}
|
|
216
|
+
assert list(shell) == [4]
|
|
217
|
+
shell = {3, 4, 5} - shell # type: ignore
|
|
218
|
+
assert isinstance(shell, ShellMutableSet)
|
|
219
|
+
assert list(shell) == [3, 5]
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def test_ShellMutableSet_mutating_operators() -> None:
|
|
223
|
+
shell = ShellMutableSet([2, 4])
|
|
224
|
+
shell |= {6}
|
|
225
|
+
assert list(shell) == [2, 4, 6]
|
|
226
|
+
shell &= {2, 6, 8}
|
|
227
|
+
assert list(shell) == [2, 6]
|
|
228
|
+
shell ^= {0, 2, 4, 6}
|
|
229
|
+
assert list(shell) == [0, 4]
|
|
230
|
+
shell -= {0, 1}
|
|
231
|
+
assert list(shell) == [4]
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def test_ShellMutableSet_errors() -> None:
|
|
235
|
+
with pytest.raises(KeyError):
|
|
236
|
+
ShellMutableSet([2]).remove(3)
|
|
237
|
+
with pytest.raises(KeyError):
|
|
238
|
+
ShellMutableSet([]).pop()
|
|
239
|
+
with pytest.raises(TypeError):
|
|
240
|
+
ShellMutableSet(4) # type: ignore
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@pytest.mark.parametrize("start", [-3, -1, 0, 1, 3, None])
|
|
244
|
+
@pytest.mark.parametrize("stop", [-2, -1, 0, 1, 2, None])
|
|
245
|
+
def test_slice_view_slice(start, stop) -> None:
|
|
246
|
+
allnums = ["0", "1", "2", "3"]
|
|
247
|
+
innernums = SliceView(allnums, 1, 3)
|
|
248
|
+
concrete = ["1", "2"][start:stop]
|
|
249
|
+
assert list(innernums[start:stop]) == concrete
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@pytest.mark.parametrize("cut", [-2, 1, 3, 7])
|
|
253
|
+
@pytest.mark.parametrize("step", [-2, -1, 1, 2, 3])
|
|
254
|
+
@pytest.mark.parametrize("stop", [0, 2, 4, 6])
|
|
255
|
+
@pytest.mark.parametrize("start", [0, 1, 2, 3, 4, 5, 6])
|
|
256
|
+
def test_cut_slice(start, stop, step, cut):
|
|
257
|
+
left, right = cut_slice(start, stop, step, cut)
|
|
258
|
+
litems = list(range(left.start, left.stop, left.step))
|
|
259
|
+
ritems = list(range(right.start, right.stop, right.step))
|
|
260
|
+
expected = list(range(start, stop, step))
|
|
261
|
+
assert expected == litems + ritems, f"{litems}+{ritems}, expected {expected}"
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@pytest.mark.parametrize("idx", [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6])
|
|
265
|
+
def test_SequenceConcatenation_indexed(idx) -> None:
|
|
266
|
+
c1 = SequenceConcatenation(SequenceConcatenation((11, 22), ()), (33,))
|
|
267
|
+
# c1 = SequenceConcatenation((11, 22), (33,))
|
|
268
|
+
c2 = [11, 22, 33]
|
|
269
|
+
r1 = summarize_execution(lambda x: c1[x], (idx,), detach_path=False)
|
|
270
|
+
expected = summarize_execution(lambda x: c2[x], (idx,), detach_path=False)
|
|
271
|
+
assert r1 == expected
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
@pytest.mark.parametrize("step", [None, -1, 1, 2, -2, 3, -3])
|
|
275
|
+
@pytest.mark.parametrize("stop", [None, 0, 2, 4, 6, -2, -4, -6])
|
|
276
|
+
@pytest.mark.parametrize("start", [None, 0, 1, 2, 3, 4, 5, 6, -1, -2, -3, -4, -5, -6])
|
|
277
|
+
def test_SequenceConcatenation_sliced(start, stop, step) -> None:
|
|
278
|
+
c1 = SequenceConcatenation((11, 22, 33), (44, 55))
|
|
279
|
+
c2 = [11, 22, 33, 44, 55]
|
|
280
|
+
s = slice(start, stop, step)
|
|
281
|
+
r1 = list(c1[s])
|
|
282
|
+
expected = c2[s]
|
|
283
|
+
assert r1 == expected
|
crosshair/smtlib.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import math
|
|
2
|
+
import re
|
|
3
|
+
import struct
|
|
4
|
+
|
|
5
|
+
_SL2_PARSE_FLOAT_RE = re.compile(r"\(fp #(b\d+) #(b\d+) #(x.+)\)")
|
|
6
|
+
LITERAL_CONSTS = {
|
|
7
|
+
"(_ -zero 11 53)": -0.0,
|
|
8
|
+
"(_ +zero 11 53)": 0.0,
|
|
9
|
+
"(_ -oo 11 53)": -math.inf,
|
|
10
|
+
"(_ +oo 11 53)": math.inf,
|
|
11
|
+
"(_ NaN 11 53)": math.nan,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def parse_smtlib_literal(input: str):
|
|
16
|
+
literal_const = LITERAL_CONSTS.get(input, None)
|
|
17
|
+
if literal_const is not None:
|
|
18
|
+
return literal_const
|
|
19
|
+
match = _SL2_PARSE_FLOAT_RE.fullmatch(input)
|
|
20
|
+
if match:
|
|
21
|
+
sign, exp, significand = (int("0" + g, base=0) for g in match.groups())
|
|
22
|
+
return struct.unpack(
|
|
23
|
+
"d", struct.pack("Q", sign << 63 | exp << 52 | significand)
|
|
24
|
+
)[0]
|
crosshair/smtlib_test.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import z3 # type: ignore
|
|
4
|
+
|
|
5
|
+
from crosshair.smtlib import parse_smtlib_literal
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_parse_smtlib_literal():
|
|
9
|
+
assert parse_smtlib_literal(z3.FPVal(1.23, z3.Float64).sexpr()) == 1.23
|
|
10
|
+
assert math.isnan(parse_smtlib_literal(z3.FPVal(math.nan, z3.Float64).sexpr()))
|
|
11
|
+
assert parse_smtlib_literal(z3.FPVal(-math.inf, z3.Float64).sexpr()) <= -math.inf
|
|
12
|
+
negzero = parse_smtlib_literal(z3.FPVal(-0.0, z3.Float64).sexpr())
|
|
13
|
+
assert negzero == 0
|
|
14
|
+
assert math.copysign(42, negzero) == -42
|