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
crosshair/copyext.py CHANGED
@@ -1,4 +1,9 @@
1
- from copy import _deepcopy_atomic # type: ignore
1
+ import sys
2
+
3
+ if sys.version_info >= (3, 14):
4
+ from copy import _atomic_types
5
+ else:
6
+ from copy import _deepcopy_atomic # type: ignore
2
7
  from copy import _deepcopy_dict # type: ignore
3
8
  from copy import _deepcopy_dispatch # type: ignore
4
9
  from copy import _deepcopy_list # type: ignore
@@ -8,10 +13,17 @@ from copy import _reconstruct # type: ignore
8
13
  from copy import Error
9
14
  from copyreg import dispatch_table # type: ignore
10
15
  from enum import Enum
11
- from typing import Any, Dict
16
+ from types import MappingProxyType
17
+ from typing import Any, Callable, Dict, Tuple
12
18
 
13
- from crosshair.tracers import is_tracing
14
- from crosshair.util import debug, test_stack
19
+ from crosshair.tracers import ResumedTracing
20
+ from crosshair.util import (
21
+ CrossHairInternal,
22
+ IdKeyedDict,
23
+ assert_tracing,
24
+ ch_stack,
25
+ debug,
26
+ )
15
27
 
16
28
  _MISSING = object
17
29
 
@@ -22,22 +34,54 @@ class CopyMode(int, Enum):
22
34
  REALIZE = 2
23
35
 
24
36
 
37
+ # We need to be able to realize some types that are not deep-copyable.
38
+ # Such realization overrides are defined here.
39
+ # TODO: This capability should probably be something that plugins can extend
40
+ _DEEP_REALIZATION_OVERRIDES = IdKeyedDict()
41
+ _DEEP_REALIZATION_OVERRIDES[MappingProxyType] = lambda p, m: MappingProxyType(
42
+ deepcopyext(dict(p), CopyMode.REALIZE, m)
43
+ )
44
+ if sys.version_info >= (3, 10):
45
+ _DEEP_REALIZATION_OVERRIDES[type({}.items())] = lambda p, m: deepcopyext(
46
+ p.mapping, CopyMode.REALIZE, m
47
+ ).items()
48
+ _DEEP_REALIZATION_OVERRIDES[type({}.keys())] = lambda p, m: deepcopyext(
49
+ p.mapping, CopyMode.REALIZE, m
50
+ ).keys()
51
+ _DEEP_REALIZATION_OVERRIDES[type({}.values())] = lambda p, m: deepcopyext(
52
+ p.mapping, CopyMode.REALIZE, m
53
+ ).values()
54
+
55
+
56
+ @assert_tracing(False)
25
57
  def deepcopyext(obj: object, mode: CopyMode, memo: Dict) -> Any:
26
- assert not is_tracing()
27
58
  objid = id(obj)
28
59
  cpy = memo.get(objid, _MISSING)
29
- if cpy is _MISSING:
60
+ if cpy is not _MISSING:
61
+ if objid not in map(id, memo.get(id(memo), ())):
62
+ # we are trying to return some value that was not kept alive;
63
+ # it may have been garbage collected and replaced.
64
+ raise CrossHairInternal("Possibly transient value found in memo")
65
+ else:
66
+ _keep_alive(obj, memo)
67
+ deepconstruct_obj = obj
30
68
  if mode == CopyMode.REALIZE:
31
69
  cls = type(obj)
32
70
  if hasattr(cls, "__ch_deep_realize__"):
33
- cpy = obj.__ch_deep_realize__() # type: ignore
71
+ cpy = obj.__ch_deep_realize__(memo) # type: ignore
34
72
  elif hasattr(cls, "__ch_realize__"):
35
73
  # Do shallow realization here, and then fall through to
36
74
  # _deepconstruct below.
37
- obj = obj.__ch_realize__() # type: ignore
75
+ deepconstruct_obj = obj.__ch_realize__() # type: ignore
76
+ # this transient object may be inserted into memo below
77
+ _keep_alive(deepconstruct_obj, memo)
78
+ else:
79
+ realization_override = _DEEP_REALIZATION_OVERRIDES.get(cls)
80
+ if realization_override:
81
+ cpy = realization_override(obj, memo)
38
82
  if cpy is _MISSING:
39
83
  try:
40
- cpy = _deepconstruct(obj, mode, memo)
84
+ cpy = _deepconstruct(deepconstruct_obj, mode, memo)
41
85
  except TypeError as exc:
42
86
  if mode == CopyMode.REGULAR:
43
87
  raise
@@ -46,41 +90,66 @@ def deepcopyext(obj: object, mode: CopyMode, memo: Dict) -> Any:
46
90
  type(obj),
47
91
  "ignoring",
48
92
  type(exc),
93
+ ":",
94
+ str(exc),
49
95
  "at",
50
- test_stack(exc.__traceback__),
96
+ ch_stack(currently_handling=exc),
51
97
  )
52
- cpy = obj
98
+ cpy = deepconstruct_obj
53
99
  memo[objid] = cpy
54
- _keep_alive(obj, memo)
55
100
  return cpy
56
101
 
57
102
 
103
+ if sys.version_info >= (3, 14):
104
+
105
+ def lookup_dispatch(cls: type) -> Callable:
106
+ if cls in _atomic_types:
107
+ return lambda obj, memo: obj
108
+ return _deepcopy_dispatch.get(cls)
109
+
110
+ else:
111
+
112
+ def lookup_dispatch(cls: type) -> Callable:
113
+ return _deepcopy_dispatch.get(cls)
114
+
115
+
58
116
  def _deepconstruct(obj: object, mode: CopyMode, memo: Dict):
59
117
  cls = type(obj)
60
118
 
61
119
  def subdeepcopy(obj: object, memo: Dict):
62
120
  return deepcopyext(obj, mode, memo)
63
121
 
64
- if cls in _deepcopy_dispatch:
65
- creator = _deepcopy_dispatch[cls]
66
- if creator is _deepcopy_atomic:
67
- return obj
68
- elif creator in (_deepcopy_dict, _deepcopy_list, _deepcopy_tuple):
122
+ creator = lookup_dispatch(cls)
123
+ if creator is not None:
124
+ if creator in (_deepcopy_dict, _deepcopy_list, _deepcopy_tuple):
69
125
  return creator(obj, memo, deepcopy=subdeepcopy)
70
126
  else:
127
+ # TODO: We loose subdeepcopy in this case - won't
128
+ # that make e.g. deep_realize be too shallow?
71
129
  return creator(obj, memo)
72
130
  if isinstance(obj, type):
73
131
  return obj
74
132
  if mode != CopyMode.REALIZE and hasattr(obj, "__deepcopy__"):
75
133
  return obj.__deepcopy__(memo) # type: ignore
76
134
  if cls in dispatch_table:
77
- reduct = dispatch_table[cls](obj)
78
- elif hasattr(obj, "__reduce_ex__"):
79
- reduct = getattr(obj, "__reduce_ex__")(4)
80
- elif hasattr(obj, "__reduce__"):
81
- reduct = getattr(obj, "__reduce__")()
135
+ to_call = dispatch_table[cls]
136
+ call_args: Tuple = (obj,)
137
+ elif hasattr(cls, "__reduce_ex__"):
138
+ to_call = getattr(cls, "__reduce_ex__")
139
+ call_args = (obj, 4)
140
+ elif hasattr(cls, "__reduce__"):
141
+ to_call = getattr(cls, "__reduce__")
142
+ call_args = (obj,)
82
143
  else:
83
144
  raise Error("un(deep)copyable object of type %s" % cls)
145
+ if (
146
+ getattr(cls, "__reduce__") is object.__reduce__
147
+ and getattr(cls, "__reduce_ex__") is object.__reduce_ex__
148
+ ):
149
+ reduct = to_call(*call_args)
150
+ else:
151
+ with ResumedTracing():
152
+ reduct = to_call(*call_args)
84
153
  if isinstance(reduct, str):
85
154
  return obj
86
155
  return _reconstruct(obj, memo, *reduct, deepcopy=subdeepcopy)
crosshair/copyext_test.py CHANGED
@@ -1,3 +1,4 @@
1
+ import sys
1
2
  from copy import deepcopy
2
3
  from threading import RLock
3
4
  from typing import Tuple
@@ -33,6 +34,16 @@ def test_deepcopyext_symbolic_set():
33
34
  deepcopyext(s, CopyMode.REALIZE, {})
34
35
 
35
36
 
37
+ def test_deepcopyext_realize_simple(space):
38
+ x = SymbolicInt("x")
39
+ input = (x,)
40
+ output = deepcopyext(input, CopyMode.REALIZE, {})
41
+ assert input is not output
42
+ assert input[0] is not output[0]
43
+ assert type(input[0]) is SymbolicInt
44
+ assert type(output[0]) is int
45
+
46
+
36
47
  def test_deepcopyext_realize(space):
37
48
  x = SymbolicInt("x")
38
49
  lock = RLock()
@@ -49,3 +60,25 @@ def test_deepcopyext_realize(space):
49
60
  def test_deepcopyext_tuple_type():
50
61
  assert deepcopy(Tuple) is Tuple
51
62
  assert deepcopyext(Tuple, CopyMode.REALIZE, {}) is Tuple
63
+
64
+
65
+ class RecursiveType:
66
+ a: "RecursiveType"
67
+
68
+ def set(self, a):
69
+ self.a = a
70
+
71
+
72
+ def test_deepcopyext_recursivetype(space):
73
+ recursive_obj = RecursiveType()
74
+ recursive_obj.set(recursive_obj)
75
+ deepcopyext(recursive_obj, CopyMode.REALIZE, {})
76
+
77
+
78
+ @pytest.mark.skipif(
79
+ sys.version_info < (3, 10), reason="dict views not inspect-able before python 3.10"
80
+ )
81
+ def test_fsum_accepts_dict_values_argument(space):
82
+ d = {"a": proxy_for_type(int, "b")}
83
+ realized_vals = deepcopyext(d.values(), CopyMode.REALIZE, {})
84
+ assert type(next(iter(realized_vals))) is int