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,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]
@@ -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