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,72 @@
1
+ import time as real_time
2
+ from inspect import Signature
3
+ from math import isfinite
4
+ from typing import Any, Literal
5
+
6
+ from crosshair.core import register_patch
7
+ from crosshair.register_contract import register_contract
8
+ from crosshair.statespace import context_statespace
9
+ from crosshair.tracers import NoTracing
10
+
11
+
12
+ class EarliestPossibleTime:
13
+ monotonic: float = 0.0
14
+ process_time: float = 0.0
15
+
16
+ def __init__(self, *a):
17
+ pass
18
+
19
+
20
+ # Imprecision at high values becomes a sort of artificial problem
21
+ _UNREALISTICALLY_LARGE_TIME_FLOAT = float(60 * 60 * 24 * 365 * 100_000)
22
+
23
+
24
+ def _gte_last(kind: Literal["monotonic", "process_time"], value: Any) -> bool:
25
+ with NoTracing():
26
+ earliest_times = context_statespace().extra(EarliestPossibleTime)
27
+ threshold = getattr(earliest_times, kind)
28
+ setattr(earliest_times, kind, value)
29
+ return all([threshold <= value, value < _UNREALISTICALLY_LARGE_TIME_FLOAT])
30
+
31
+
32
+ def _sleep(value: float) -> None:
33
+ with NoTracing():
34
+ earliest_times = context_statespace().extra(EarliestPossibleTime)
35
+ earliest_times.monotonic += value
36
+ return None
37
+
38
+
39
+ def make_registrations():
40
+ register_contract(
41
+ real_time.time,
42
+ post=lambda __return__: __return__ > 0.0 and isfinite(__return__),
43
+ sig=Signature(parameters=[], return_annotation=float),
44
+ )
45
+ register_contract(
46
+ real_time.time_ns,
47
+ post=lambda __return__: __return__ > 0,
48
+ sig=Signature(parameters=[], return_annotation=int),
49
+ )
50
+ register_contract(
51
+ real_time.monotonic,
52
+ post=lambda __return__: _gte_last("monotonic", __return__)
53
+ and isfinite(__return__),
54
+ sig=Signature(parameters=[], return_annotation=float),
55
+ )
56
+ register_contract(
57
+ real_time.monotonic_ns,
58
+ post=lambda __return__: _gte_last("monotonic", __return__ / 1_000_000_000),
59
+ sig=Signature(parameters=[], return_annotation=int),
60
+ )
61
+ register_contract(
62
+ real_time.process_time,
63
+ post=lambda __return__: _gte_last("process_time", __return__)
64
+ and isfinite(__return__),
65
+ sig=Signature(parameters=[], return_annotation=float),
66
+ )
67
+ register_contract(
68
+ real_time.process_time_ns,
69
+ post=lambda __return__: _gte_last("process_time", __return__ / 1_000_000_000),
70
+ sig=Signature(parameters=[], return_annotation=int),
71
+ )
72
+ register_patch(real_time.sleep, _sleep)
@@ -0,0 +1,82 @@
1
+ import time
2
+
3
+ import pytest
4
+
5
+ from crosshair.statespace import CANNOT_CONFIRM, CONFIRMED, POST_FAIL
6
+ from crosshair.test_util import check_states
7
+
8
+
9
+ @pytest.mark.demo
10
+ def test_time():
11
+ def f():
12
+ """
13
+ Can time go backwards?
14
+
15
+ NOTE: CrossHair allows time() to produce ANY value.
16
+ Although highly unlikely, it's possible that the system clock
17
+ is set backwards while a program executes.
18
+ (BTW: use time.monotonic if you don't want it to go backwards!)
19
+
20
+ CrossHair's counterexample includes a monkey-patching context
21
+ manager that lets you reproduce the issue, e.g.:
22
+ with crosshair.patch_to_return({time.time: [2.0, 1.0]}):
23
+ f()
24
+
25
+ post: _ >= 0
26
+ """
27
+ start = time.time()
28
+ return time.time() - start
29
+
30
+ check_states(f, POST_FAIL)
31
+
32
+
33
+ def test_time_ns():
34
+ def f():
35
+ """post: _ >= 0"""
36
+ start = time.time_ns()
37
+ return time.time_ns() - start
38
+
39
+ check_states(f, POST_FAIL)
40
+
41
+
42
+ @pytest.mark.demo
43
+ def test_monotonic():
44
+ def f():
45
+ """
46
+ Can time increase by one second between monotonic() calls?
47
+
48
+ post: _ != 1.0
49
+ """
50
+ start = time.monotonic()
51
+ end = time.monotonic()
52
+ return end - start
53
+
54
+ check_states(f, POST_FAIL)
55
+
56
+
57
+ def test_monotonic_confirm():
58
+ def f():
59
+ """post: _ >= 0"""
60
+ start = time.monotonic()
61
+ return time.monotonic() - start
62
+
63
+ check_states(f, CONFIRMED)
64
+
65
+
66
+ def test_monotonic_ns():
67
+ def f():
68
+ """post: _ >= 0"""
69
+ start = time.monotonic_ns()
70
+ return time.monotonic_ns() - start
71
+
72
+ check_states(f, CANNOT_CONFIRM)
73
+
74
+
75
+ def test_sleep():
76
+ def f():
77
+ """post: _ >= 60.0"""
78
+ start = time.monotonic()
79
+ time.sleep(60.01)
80
+ return time.monotonic() - start
81
+
82
+ check_states(f, CANNOT_CONFIRM)
@@ -0,0 +1,15 @@
1
+ from types import MappingProxyType
2
+ from typing import Any, Dict
3
+
4
+ from crosshair.core import register_patch, register_type
5
+
6
+
7
+ def _repr(map: MappingProxyType):
8
+ if not isinstance(map, MappingProxyType):
9
+ raise TypeError
10
+ return f"mappingproxy({repr(dict(map))})"
11
+
12
+
13
+ def make_registrations():
14
+ register_type(MappingProxyType, lambda p, kt=Any, vt=Any: MappingProxyType(p(Dict[kt, vt]))) # type: ignore
15
+ register_patch(MappingProxyType.__repr__, _repr)
@@ -0,0 +1,36 @@
1
+ import sys
2
+ from types import MappingProxyType
3
+ from typing import Dict
4
+
5
+ import pytest
6
+
7
+ from crosshair import ResumedTracing
8
+ from crosshair.core import deep_realize, proxy_for_type
9
+ from crosshair.libimpl.builtinslib import SymbolicInt
10
+
11
+
12
+ @pytest.mark.skipif(
13
+ sys.version_info < (3, 9), reason="MappingProxyType not subscriptable in 3.8"
14
+ )
15
+ def test_mappingproxy_repr(space):
16
+ d = proxy_for_type(MappingProxyType[int, int], "d")
17
+ with ResumedTracing():
18
+ assert repr(d).startswith("mappingproxy(")
19
+
20
+
21
+ def test_mappingproxy_deep_realize(space):
22
+ inner = proxy_for_type(Dict[int, int], "inner")
23
+ with ResumedTracing():
24
+ space.add(inner._inner.__len__() == 1)
25
+ key = next(iter(inner.keys()))
26
+ assert type(key) is SymbolicInt
27
+ orig = MappingProxyType(inner)
28
+ assert type(orig) is MappingProxyType
29
+ copy = deep_realize(orig)
30
+ assert type(copy) is MappingProxyType
31
+ with ResumedTracing():
32
+ val_from_orig = orig[key]
33
+ realized_key = deep_realize(key)
34
+ val_from_copy = copy[realized_key]
35
+ assert type(val_from_orig) is SymbolicInt
36
+ assert type(val_from_copy) is int
@@ -0,0 +1,75 @@
1
+ import sys
2
+ import unicodedata
3
+
4
+ from crosshair.core import register_patch, with_realized_args
5
+ from crosshair.libimpl.builtinslib import AnySymbolicStr, SymbolicInt
6
+ from crosshair.statespace import context_statespace
7
+ from crosshair.tracers import NoTracing
8
+ from crosshair.unicode_categories import UnicodeMaskCache
9
+
10
+
11
+ def _decimal(ch: str) -> float:
12
+ codepoint = ord(ch)
13
+ with NoTracing():
14
+ if not isinstance(ch, AnySymbolicStr):
15
+ return unicodedata.decimal(ch)
16
+ space = context_statespace()
17
+ smt_codepoint = SymbolicInt._coerce_to_smt_sort(codepoint)
18
+ cache = space.extra(UnicodeMaskCache)
19
+ if not space.smt_fork(cache.decimal_exists()(smt_codepoint)):
20
+ raise ValueError
21
+ return SymbolicInt(cache.decimal_int()(smt_codepoint))
22
+
23
+
24
+ def _digit(ch: str) -> float:
25
+ codepoint = ord(ch)
26
+ with NoTracing():
27
+ if not isinstance(ch, AnySymbolicStr):
28
+ return unicodedata.digit(ch)
29
+ space = context_statespace()
30
+ smt_codepoint = SymbolicInt._coerce_to_smt_sort(codepoint)
31
+ cache = space.extra(UnicodeMaskCache)
32
+ if not space.smt_fork(cache.digit_exists()(smt_codepoint)):
33
+ raise ValueError
34
+ return SymbolicInt(cache.digit_int()(smt_codepoint))
35
+
36
+
37
+ def _numeric(ch: str) -> float:
38
+ codepoint = ord(ch)
39
+ with NoTracing():
40
+ if not isinstance(ch, AnySymbolicStr):
41
+ return unicodedata.numeric(ch)
42
+ space = context_statespace()
43
+ smt_codepoint = SymbolicInt._coerce_to_smt_sort(codepoint)
44
+ cache = space.extra(UnicodeMaskCache)
45
+ if not space.smt_fork(cache.numeric_exists()(smt_codepoint)):
46
+ raise ValueError
47
+ numerator = SymbolicInt(cache.numeric_numerator()(smt_codepoint))
48
+ denominator = SymbolicInt(cache.numeric_denominator()(smt_codepoint))
49
+ return numerator / float(denominator)
50
+
51
+
52
+ def make_registrations():
53
+ register_patch(unicodedata.lookup, with_realized_args(unicodedata.lookup))
54
+ register_patch(unicodedata.name, with_realized_args(unicodedata.name))
55
+ register_patch(unicodedata.decimal, _decimal)
56
+ register_patch(unicodedata.digit, _digit)
57
+ register_patch(unicodedata.numeric, _numeric)
58
+ # TOOD: implement this using get_unicode_categories() - should be easy:
59
+ register_patch(unicodedata.category, with_realized_args(unicodedata.category))
60
+ register_patch(
61
+ unicodedata.bidirectional, with_realized_args(unicodedata.bidirectional)
62
+ )
63
+ register_patch(unicodedata.combining, with_realized_args(unicodedata.combining))
64
+ register_patch(
65
+ unicodedata.east_asian_width, with_realized_args(unicodedata.east_asian_width)
66
+ )
67
+ register_patch(unicodedata.mirrored, with_realized_args(unicodedata.mirrored))
68
+ register_patch(
69
+ unicodedata.decomposition, with_realized_args(unicodedata.decomposition)
70
+ )
71
+ register_patch(unicodedata.normalize, with_realized_args(unicodedata.normalize))
72
+ if sys.version_info >= (3, 8):
73
+ register_patch(
74
+ unicodedata.is_normalized, with_realized_args(unicodedata.is_normalized)
75
+ )
@@ -0,0 +1,42 @@
1
+ import unicodedata
2
+ from typing import *
3
+
4
+ import pytest
5
+
6
+ from crosshair.core_and_libs import NoTracing, standalone_statespace
7
+ from crosshair.libimpl.builtinslib import LazyIntSymbolicStr
8
+
9
+
10
+ def test_numeric():
11
+ with standalone_statespace as space:
12
+ with NoTracing():
13
+ fourstr = LazyIntSymbolicStr(list(map(ord, "4")))
14
+ halfstr = LazyIntSymbolicStr(list(map(ord, "\u00bd"))) # (1/2 character)
15
+ four = unicodedata.numeric(fourstr)
16
+ half = unicodedata.numeric(halfstr)
17
+ assert type(four) is float
18
+ assert four == 4.0
19
+ assert half == 0.5
20
+
21
+
22
+ def test_decimal():
23
+ with standalone_statespace as space:
24
+ with NoTracing():
25
+ thai4 = LazyIntSymbolicStr(list(map(ord, "\u0e54"))) # (Thai numerial 4)
26
+ super4 = LazyIntSymbolicStr(list(map(ord, "\u2074"))) # (superscript 4)
27
+ four = unicodedata.decimal(thai4)
28
+ assert type(four) is int
29
+ assert four == 4
30
+ with pytest.raises(ValueError):
31
+ unicodedata.decimal(super4)
32
+
33
+
34
+ def test_digit():
35
+ with standalone_statespace as space:
36
+ with NoTracing():
37
+ thai4 = LazyIntSymbolicStr(list(map(ord, "\u0e54"))) # (Thai numerial 4)
38
+ super4 = LazyIntSymbolicStr(list(map(ord, "\u2074"))) # (superscript 4)
39
+ four = unicodedata.digit(thai4)
40
+ assert type(four) is int
41
+ assert four == 4
42
+ assert unicodedata.digit(super4) == 4
@@ -0,0 +1,23 @@
1
+ import sys
2
+ import urllib.parse
3
+
4
+
5
+ class DevNullDict:
6
+ def get(self, k, default):
7
+ return default
8
+
9
+ def __setitem__(self, k, v):
10
+ pass
11
+
12
+ def __len__(self):
13
+ return 0
14
+
15
+
16
+ def make_registrations():
17
+ # Avoid nondeterminism in urllib by disabling internal caching.
18
+ if sys.version_info < (3, 11):
19
+ # TODO: This is destructive! But not terribly harmful. Consider alternatives.
20
+ urllib.parse._parse_cache = DevNullDict() # type: ignore
21
+ else:
22
+ # (3.11 uses functools.lru_cache, which we disable elsewhere)
23
+ assert not hasattr(urllib.parse, "_parse_cache")
@@ -0,0 +1,19 @@
1
+ from urllib.parse import urlparse
2
+
3
+ from crosshair.options import AnalysisOptionSet
4
+ from crosshair.statespace import POST_FAIL, MessageType
5
+ from crosshair.test_util import check_states
6
+
7
+
8
+ def test_urllib_parse():
9
+ def f(urlstring: str):
10
+ """
11
+ pre: len(urlstring) == 3
12
+ pre: urlstring[0:2] == "//"
13
+ pre: urlstring[2] != "["
14
+ pre: urlstring[2] != "]"
15
+ post: __return__.netloc != "h"
16
+ """
17
+ return urlparse(urlstring)
18
+
19
+ check_states(f, POST_FAIL)
@@ -0,0 +1,13 @@
1
+ from weakref import ref
2
+
3
+ from crosshair.core import register_patch
4
+
5
+
6
+ def _ref_call(r):
7
+ if not isinstance(r, ref):
8
+ raise TypeError
9
+ return None
10
+
11
+
12
+ def make_registrations():
13
+ register_patch(ref.__call__, _ref_call)
@@ -0,0 +1,69 @@
1
+ from weakref import WeakKeyDictionary, WeakSet, WeakValueDictionary, proxy, ref
2
+
3
+ import pytest
4
+
5
+ from crosshair.tracers import ResumedTracing
6
+
7
+
8
+ class Thing:
9
+ x: int = 0
10
+
11
+
12
+ def test_weakref(space):
13
+ thing1 = Thing()
14
+ assert ref(thing1)() is thing1
15
+ with ResumedTracing():
16
+ assert ref(thing1)() is None
17
+
18
+
19
+ def test_weakref_WeakKeyDictionary(space):
20
+ d = WeakKeyDictionary()
21
+ thing1 = Thing()
22
+ thing2 = Thing()
23
+ d[thing1] = 1
24
+ d[thing2] = 2
25
+ assert len(d) == 2
26
+ assert thing1 in d
27
+ assert set(d.keys()) == {thing1, thing2}
28
+ with ResumedTracing():
29
+ assert set(d.keys()) == set()
30
+ # You would expect the following assertions to work too
31
+ # However, they don't require getting the referred object, so they appear to still exist:
32
+ # assert thing1 not in d
33
+ # assert len(d) == 0
34
+
35
+
36
+ def test_weakref_WeakValueDictionary(space):
37
+ d = WeakValueDictionary()
38
+ thing1 = Thing()
39
+ thing2 = Thing()
40
+ d[1] = thing1
41
+ d[2] = thing2
42
+ assert len(d) == 2
43
+ assert 1 in d
44
+ assert set(d.keys()) == {1, 2}
45
+ with ResumedTracing():
46
+ assert set(d.keys()) == set()
47
+ assert 1 not in d
48
+ # You would expect the length to update too.
49
+ # However, it doesn't require getting the referred object, so it appears to still exist:
50
+ # assert len(d) == 0
51
+
52
+
53
+ @pytest.mark.xfail(reason="weakref.WeakSet is not yet supported")
54
+ def test_weakref_WeakSet(space):
55
+ s = WeakSet()
56
+ thing1 = Thing()
57
+ s.add(thing1)
58
+ assert thing1 in s
59
+ with ResumedTracing():
60
+ assert thing1 not in s
61
+
62
+
63
+ @pytest.mark.xfail(reason="weakref.proxy is not yet supported")
64
+ def test_weakref_proxy(space):
65
+ thing1 = Thing()
66
+ thing1.x
67
+ p = proxy(thing1)
68
+ with pytest.raises(ReferenceError), ResumedTracing():
69
+ p.x
@@ -0,0 +1,15 @@
1
+ import zlib
2
+
3
+ from crosshair.core import register_patch, with_realized_args
4
+
5
+
6
+ def make_registrations():
7
+ for fn in (
8
+ zlib.adler32,
9
+ zlib.compress,
10
+ zlib.crc32,
11
+ zlib.decompress,
12
+ type(zlib.compressobj()).compress,
13
+ type(zlib.decompressobj()).decompress,
14
+ ):
15
+ register_patch(fn, with_realized_args(fn))
@@ -0,0 +1,13 @@
1
+ import zlib
2
+
3
+ from crosshair.core import proxy_for_type, realize
4
+ from crosshair.tracers import ResumedTracing
5
+
6
+
7
+ def test_compress_on_symbolic(space):
8
+ buffer = proxy_for_type(bytes, "buffer")
9
+ with ResumedTracing():
10
+ space.add(len(buffer) == 1)
11
+ result = zlib.compress(buffer)
12
+ realized_buffer = realize(buffer)
13
+ assert zlib.decompress(result) == realized_buffer