crosshair-tool 0.0.96__cp38-cp38-musllinux_1_2_x86_64.whl → 0.0.97__cp38-cp38-musllinux_1_2_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.

Potentially problematic release.


This version of crosshair-tool might be problematic. Click here for more details.

Files changed (38) hide show
  1. _crosshair_tracers.cpython-38-x86_64-linux-gnu.so +0 -0
  2. crosshair/__init__.py +1 -1
  3. crosshair/_tracers_test.py +5 -5
  4. crosshair/codeconfig.py +3 -2
  5. crosshair/condition_parser.py +1 -0
  6. crosshair/core.py +6 -8
  7. crosshair/dynamic_typing.py +3 -3
  8. crosshair/enforce.py +1 -0
  9. crosshair/examples/check_examples_test.py +1 -0
  10. crosshair/fnutil.py +2 -3
  11. crosshair/fnutil_test.py +1 -4
  12. crosshair/fuzz_core_test.py +9 -1
  13. crosshair/libimpl/arraylib.py +1 -1
  14. crosshair/libimpl/builtinslib.py +12 -8
  15. crosshair/libimpl/builtinslib_ch_test.py +3 -3
  16. crosshair/libimpl/builtinslib_test.py +2 -1
  17. crosshair/libimpl/datetimelib.py +1 -3
  18. crosshair/libimpl/datetimelib_ch_test.py +5 -5
  19. crosshair/libimpl/encodings/_encutil.py +11 -6
  20. crosshair/libimpl/relib.py +1 -1
  21. crosshair/libimpl/unicodedatalib_test.py +3 -3
  22. crosshair/main.py +5 -3
  23. crosshair/opcode_intercept.py +37 -1
  24. crosshair/pathing_oracle.py +1 -1
  25. crosshair/pathing_oracle_test.py +1 -1
  26. crosshair/register_contract.py +1 -0
  27. crosshair/register_contract_test.py +2 -4
  28. crosshair/simplestructs.py +10 -8
  29. crosshair/statespace.py +1 -1
  30. crosshair/tools/generate_demo_table.py +2 -2
  31. crosshair/tracers.py +8 -6
  32. crosshair/util.py +6 -6
  33. {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/METADATA +4 -5
  34. {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/RECORD +38 -38
  35. {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/LICENSE +0 -0
  36. {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/WHEEL +0 -0
  37. {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/entry_points.txt +0 -0
  38. {crosshair_tool-0.0.96.dist-info → crosshair_tool-0.0.97.dist-info}/top_level.txt +0 -0
crosshair/__init__.py CHANGED
@@ -15,7 +15,7 @@ from crosshair.statespace import StateSpace
15
15
  from crosshair.tracers import NoTracing, ResumedTracing
16
16
  from crosshair.util import IgnoreAttempt, debug
17
17
 
18
- __version__ = "0.0.96" # Do not forget to update in setup.py!
18
+ __version__ = "0.0.97" # Do not forget to update in setup.py!
19
19
  __author__ = "Phillip Schanely"
20
20
  __license__ = "MIT"
21
21
  __status__ = "Alpha"
@@ -19,19 +19,19 @@ class ExampleModule:
19
19
 
20
20
  def test_CTracer_module_refcounts_dont_leak():
21
21
  mod = ExampleModule()
22
- assert sys.getrefcount(mod) == 2
22
+ base_count = sys.getrefcount(mod)
23
23
  tracer = CTracer()
24
24
  tracer.push_module(mod)
25
- assert sys.getrefcount(mod) == 3
25
+ assert sys.getrefcount(mod) == base_count + 1
26
26
  tracer.push_module(mod)
27
27
  tracer.start()
28
28
  tracer.stop()
29
- assert sys.getrefcount(mod) == 4
29
+ assert sys.getrefcount(mod) == base_count + 2
30
30
  tracer.pop_module(mod)
31
- assert sys.getrefcount(mod) == 3
31
+ assert sys.getrefcount(mod) == base_count + 1
32
32
  del tracer
33
33
  gc.collect()
34
- assert sys.getrefcount(mod) == 2
34
+ assert sys.getrefcount(mod) == base_count
35
35
 
36
36
 
37
37
  def _get_depths(fn):
crosshair/codeconfig.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Configure analysis options at different levels."""
2
+
2
3
  import importlib.resources
3
4
  import inspect
4
5
  import re
@@ -25,7 +26,7 @@ def get_directives(source_text: str) -> Iterable[Tuple[int, int, str]]:
25
26
  ret = []
26
27
  tokens = tokenize.generate_tokens(StringIO(source_text).readline)
27
28
  # TODO catch tokenize.TokenError ... just in case?
28
- for (toktyp, tokval, begin, _, _) in tokens:
29
+ for toktyp, tokval, begin, _, _ in tokens:
29
30
  linenum, colnum = begin
30
31
  if toktyp == tokenize.COMMENT:
31
32
  directive = _COMMENT_TOKEN_RE.sub(r"\1", tokval)
@@ -39,7 +40,7 @@ class InvalidDirective(Exception):
39
40
 
40
41
 
41
42
  def parse_directives(
42
- directive_lines: Iterable[Tuple[int, int, str]]
43
+ directive_lines: Iterable[Tuple[int, int, str]],
43
44
  ) -> AnalysisOptionSet:
44
45
  """
45
46
  Parse options from directives in comments.
@@ -520,6 +520,7 @@ class ConcreteConditionParser(ConditionParser):
520
520
  "__delattr__",
521
521
  "__replace__", # Will raise an exception with most arbitrary **kwargs.
522
522
  "__annotate__", # a staticmethod, but not isinstance(staticmethod)
523
+ "__annotate_func__",
523
524
  ):
524
525
  pass
525
526
  elif method_name == "__del__":
crosshair/core.py CHANGED
@@ -563,12 +563,12 @@ class SymbolicFactory:
563
563
  @overload
564
564
  def __call__(
565
565
  self, typ: Callable[..., _T], suffix: str = "", allow_subtypes: bool = True
566
- ) -> _T:
567
- ...
566
+ ) -> _T: ...
568
567
 
569
568
  @overload
570
- def __call__(self, typ: Any, suffix: str = "", allow_subtypes: bool = True) -> Any:
571
- ...
569
+ def __call__(
570
+ self, typ: Any, suffix: str = "", allow_subtypes: bool = True
571
+ ) -> Any: ...
572
572
 
573
573
  def __call__(self, typ, suffix: str = "", allow_subtypes: bool = True):
574
574
  """
@@ -653,8 +653,7 @@ def proxy_for_type(
653
653
  typ: Callable[..., _T],
654
654
  varname: str,
655
655
  allow_subtypes: bool = False,
656
- ) -> _T:
657
- ...
656
+ ) -> _T: ...
658
657
 
659
658
 
660
659
  @overload
@@ -662,8 +661,7 @@ def proxy_for_type(
662
661
  typ: Any,
663
662
  varname: str,
664
663
  allow_subtypes: bool = False,
665
- ) -> Any:
666
- ...
664
+ ) -> Any: ...
667
665
 
668
666
 
669
667
  def proxy_for_type(
@@ -59,7 +59,7 @@ def unify_callable_args(
59
59
  return True
60
60
  if len(value_types) != len(recv_types):
61
61
  return False
62
- for (varg, rarg) in zip(value_types, recv_types):
62
+ for varg, rarg in zip(value_types, recv_types):
63
63
  # note reversal here: Callable is contravariant in argument types
64
64
  if not unify(rarg, varg, bindings):
65
65
  return False
@@ -206,7 +206,7 @@ def unify(
206
206
  vargs = [object for _ in rargs]
207
207
  else:
208
208
  return False
209
- for (varg, targ) in zip(vargs, rargs):
209
+ for varg, targ in zip(vargs, rargs):
210
210
  if not unify(varg, targ, bindings):
211
211
  return False
212
212
  return True
@@ -302,7 +302,7 @@ def intersect_signatures(
302
302
  is_squishy1 = var_pos1 is not None or var_key1 is not None
303
303
  is_squishy2 = var_pos2 is not None or var_key2 is not None
304
304
  out_params: Dict[str, Parameter] = {}
305
- for (p1, p2) in zip_longest(pos1, pos2):
305
+ for p1, p2 in zip_longest(pos1, pos2):
306
306
  if p1 is None:
307
307
  if is_squishy1:
308
308
  out_params[p2.name] = p2
crosshair/enforce.py CHANGED
@@ -36,6 +36,7 @@ def WithEnforcement(fn: Callable) -> Callable:
36
36
  Enforcement is normally disabled when calling from some internal files, for
37
37
  performance reasons. Use WithEnforcement to ensure it is enabled anywhere.
38
38
  """
39
+
39
40
  # This local function has a special name that we look for while tracing
40
41
  # (see the wants_codeobj method below):
41
42
  def _crosshair_with_enforcement(*a, **kw):
@@ -1,4 +1,5 @@
1
1
  """Run functional tests of the tool on all the examples."""
2
+
2
3
  import argparse
3
4
  import os
4
5
  import pathlib
crosshair/fnutil.py CHANGED
@@ -41,8 +41,7 @@ if sys.version_info >= (3, 8):
41
41
  from typing import Protocol
42
42
 
43
43
  class Descriptor(Protocol):
44
- def __get__(self, instance: object, cls: type) -> Any:
45
- ...
44
+ def __get__(self, instance: object, cls: type) -> Any: ...
46
45
 
47
46
  else:
48
47
  Descriptor = Any
@@ -344,7 +343,7 @@ def walk_paths(paths: Iterable[Path], ignore_missing=False) -> Iterable[Path]:
344
343
  else:
345
344
  raise FileNotFoundError(str(path))
346
345
  if path.is_dir():
347
- for (dirpath, _dirs, files) in os.walk(str(path)):
346
+ for dirpath, _dirs, files in os.walk(str(path)):
348
347
  for curfile in files:
349
348
  if analyzable_filename(curfile):
350
349
  yield Path(dirpath) / curfile
crosshair/fnutil_test.py CHANGED
@@ -26,10 +26,7 @@ def test_fn_globals_on_builtin() -> None:
26
26
 
27
27
  def test_resolve_signature_invalid_annotations() -> None:
28
28
  sig = resolve_signature(with_invalid_type_annotation)
29
- if sys.version_info >= (3, 14):
30
- assert sig == "TypeThatIsNotDefined"
31
- else:
32
- assert sig == "name 'TypeThatIsNotDefined' is not defined"
29
+ assert sig == "name 'TypeThatIsNotDefined' is not defined"
33
30
 
34
31
 
35
32
  @pytest.mark.skipif(
@@ -47,7 +47,7 @@ from crosshair.statespace import (
47
47
  from crosshair.stubs_parser import signature_from_stubs
48
48
  from crosshair.test_util import flexible_equal
49
49
  from crosshair.tracers import COMPOSITE_TRACER, NoTracing, ResumedTracing
50
- from crosshair.util import CrosshairUnsupported, debug, type_args_of
50
+ from crosshair.util import CrosshairUnsupported, debug, is_iterable, type_args_of
51
51
 
52
52
  FUZZ_SEED = 1348
53
53
 
@@ -267,6 +267,14 @@ class FuzzTester:
267
267
  ) -> object:
268
268
  for name in typed_args.keys():
269
269
  literal, symbolic = literal_args[name], symbolic_args[name]
270
+ with NoTracing():
271
+ # TODO: transition into general purpose SMT expr extractor
272
+ # for equality with constant
273
+ if hasattr(symbolic, "_smt_promote_literal"):
274
+ symbolic.var = symbolic._smt_promote_literal(literal) # type: ignore
275
+ elif is_iterable(literal) and is_iterable(symbolic):
276
+ with ResumedTracing():
277
+ space.add(len(literal) == len(symbolic)) # type: ignore
270
278
  if literal != symbolic:
271
279
  raise IgnoreAttempt(
272
280
  f'symbolic "{name}" not equal to literal "{name}"'
@@ -32,7 +32,7 @@ INT_TYPE_SIZE = {c: array(c).itemsize for c in INT_TYPE_BOUNDS.keys()}
32
32
 
33
33
  def pick_code(space: StateSpace) -> Tuple[str, int, int]:
34
34
  last_idx = len(INT_TYPE_BOUNDS) - 1
35
- for (idx, (code, rng)) in enumerate(INT_TYPE_BOUNDS.items()):
35
+ for idx, (code, rng) in enumerate(INT_TYPE_BOUNDS.items()):
36
36
  if idx < last_idx:
37
37
  if space.smt_fork(desc=f"not_{code}_array"):
38
38
  continue
@@ -189,6 +189,7 @@ def smt_not(x: object) -> Union[bool, "SymbolicBool"]:
189
189
 
190
190
  _NONHEAP_PYTYPES = set([int, float, bool, NoneType, complex])
191
191
 
192
+
192
193
  # TODO: isn't this pretty close to isinstance(typ, AtomicSymbolicValue)?
193
194
  def pytype_uses_heap(typ: Type) -> bool:
194
195
  return not (typ in _NONHEAP_PYTYPES)
@@ -900,6 +901,7 @@ def setup_binops():
900
901
  if isinstance(a, FiniteFloat)
901
902
  else a.var
902
903
  )
904
+ assert smt_a is not None
903
905
  if isinstance(b, NonFiniteFloat):
904
906
  if isnan(b.val):
905
907
  return (nan, nan)
@@ -912,6 +914,7 @@ def setup_binops():
912
914
  return (-1.0, b.val)
913
915
  else:
914
916
  return (0.0, a.val if isinstance(a, FiniteFloat) else a)
917
+ assert smt_b is not None
915
918
 
916
919
  remainder = z3.Real(f"remainder{space.uniq()}")
917
920
  modproduct = z3.Int(f"modproduct{space.uniq()}")
@@ -1591,6 +1594,7 @@ class RealBasedSymbolicFloat(SymbolicFloat):
1591
1594
  denominator = SymbolicInt("denominator" + space.uniq())
1592
1595
  space.add(denominator.var > 0)
1593
1596
  space.add(numerator.var == denominator.var * self.var)
1597
+
1594
1598
  # There are many valid integer ratios to return. Experimentally, both
1595
1599
  # z3 and CPython tend to pick the same ones. But verify this, while
1596
1600
  # deferring materialization:
@@ -2330,7 +2334,7 @@ class SymbolicRange:
2330
2334
  return False
2331
2335
  if len(self) != len(other):
2332
2336
  return False
2333
- for (v1, v2) in zip(self, other):
2337
+ for v1, v2 in zip(self, other):
2334
2338
  if v1 != v2:
2335
2339
  return False
2336
2340
  return True
@@ -2783,7 +2787,7 @@ class SymbolicBoundedIntTuple(collections.abc.Sequence):
2783
2787
  with NoTracing():
2784
2788
  self._create_up_to(realize(otherlen))
2785
2789
  constraints = []
2786
- for (int1, int2) in zip(self._created_vars, tracing_iter(other)):
2790
+ for int1, int2 in zip(self._created_vars, tracing_iter(other)):
2787
2791
  smtint2 = force_to_smt_sort(int2, SymbolicInt)
2788
2792
  constraints.append(int1.var == smtint2)
2789
2793
  return SymbolicBool(z3.And(*constraints))
@@ -2910,7 +2914,7 @@ class AnySymbolicStr(AbcString):
2910
2914
  raise TypeError
2911
2915
  if self == other:
2912
2916
  return True if op in (ops.le, ops.ge) else False
2913
- for (mych, otherch) in zip_longest(iter(self), iter(other)):
2917
+ for mych, otherch in zip_longest(iter(self), iter(other)):
2914
2918
  if mych == otherch:
2915
2919
  continue
2916
2920
  if mych is None:
@@ -3172,7 +3176,7 @@ class AnySymbolicStr(AbcString):
3172
3176
 
3173
3177
  else:
3174
3178
  raise TypeError
3175
- for (idx, ch) in enumerate(self):
3179
+ for idx, ch in enumerate(self):
3176
3180
  if not filter(ch):
3177
3181
  return self[idx:]
3178
3182
  return ""
@@ -3184,7 +3188,7 @@ class AnySymbolicStr(AbcString):
3184
3188
  mylen = self.__len__()
3185
3189
  if mylen == 0:
3186
3190
  return []
3187
- for (idx, ch) in enumerate(self):
3191
+ for idx, ch in enumerate(self):
3188
3192
  codepoint = ord(ch)
3189
3193
  with NoTracing():
3190
3194
  space = context_statespace()
@@ -4008,7 +4012,7 @@ class SymbolicByteArray(BytesLike, ShellMutableSequence): # type: ignore
4008
4012
 
4009
4013
 
4010
4014
  class SymbolicMemoryView(BytesLike):
4011
- format = "B"
4015
+ format = "B" # type: ignore
4012
4016
  itemsize = 1
4013
4017
  ndim = 1
4014
4018
  strides = (1,)
@@ -4817,11 +4821,11 @@ def _str_percent_format(self, other):
4817
4821
  return self.__mod__(deep_realize(other))
4818
4822
 
4819
4823
 
4820
- def _bytes_join(self, itr) -> str:
4824
+ def _bytes_join(self, itr) -> bytes:
4821
4825
  return _join(self, itr, self_type=bytes, item_type=Buffer)
4822
4826
 
4823
4827
 
4824
- def _bytearray_join(self, itr) -> str:
4828
+ def _bytearray_join(self, itr) -> bytes:
4825
4829
  return _join(self, itr, self_type=bytearray, item_type=Buffer)
4826
4830
 
4827
4831
 
@@ -178,7 +178,7 @@ def check_iter(obj: Union[str, List[int], Dict[int, int]]) -> ResultComparison:
178
178
 
179
179
 
180
180
  def check_len(
181
- 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]],
182
182
  ) -> ResultComparison:
183
183
  """post: _"""
184
184
  return compare_results(len, s)
@@ -984,7 +984,7 @@ def check_bytes___init__(source: Union[int, List[int], bytes, bytearray, memoryv
984
984
 
985
985
 
986
986
  def check_bytearray___init__(
987
- source: Union[int, List[int], bytes, bytearray, memoryview]
987
+ source: Union[int, List[int], bytes, bytearray, memoryview],
988
988
  ):
989
989
  """
990
990
  post: _
@@ -994,7 +994,7 @@ def check_bytearray___init__(
994
994
 
995
995
 
996
996
  def check_memoryview___init__(
997
- source: Union[int, List[int], bytes, bytearray, memoryview]
997
+ source: Union[int, List[int], bytes, bytearray, memoryview],
998
998
  ):
999
999
  """
1000
1000
  post: _
@@ -1450,7 +1450,7 @@ def test_str_lower():
1450
1450
 
1451
1451
 
1452
1452
  def test_str_title():
1453
- chr_lj = "\u01C9" # "lj"
1453
+ chr_lj = "\u01c9" # "lj"
1454
1454
  chr_Lj = "\u01c8" # "Lj" (different from "LJ", "\u01c7")
1455
1455
  with standalone_statespace:
1456
1456
  with NoTracing():
@@ -2649,6 +2649,7 @@ if sys.version_info >= (3, 9):
2649
2649
  def test_set_basic_fail() -> None:
2650
2650
  def f(a: Set[int], k: int) -> None:
2651
2651
  """
2652
+ pre: len(a) <= 2
2652
2653
  post[a]: k+1 in a
2653
2654
  """
2654
2655
  a.add(k)
@@ -627,9 +627,7 @@ class timedelta:
627
627
 
628
628
  def total_seconds(self):
629
629
  """Total seconds in the duration."""
630
- return (
631
- (self.days * 86400 + self.seconds) * 10**6 + self.microseconds
632
- ) / 10**6
630
+ return ((self.days * 86400 + self.seconds) * 10**6 + self.microseconds) / 10**6
633
631
 
634
632
  # Read-only field accessors
635
633
  @property
@@ -29,7 +29,7 @@ def check_datetimelib_lt(
29
29
  Tuple[timedelta, timedelta],
30
30
  Tuple[date, datetime],
31
31
  Tuple[datetime, datetime],
32
- ]
32
+ ],
33
33
  ) -> ResultComparison:
34
34
  """post: _"""
35
35
  return compare_results(operator.lt, *p)
@@ -40,7 +40,7 @@ def check_datetimelib_add(
40
40
  Tuple[timedelta, timedelta],
41
41
  Tuple[date, timedelta],
42
42
  Tuple[timedelta, datetime],
43
- ]
43
+ ],
44
44
  ) -> ResultComparison:
45
45
  """post: _"""
46
46
  return compare_results(operator.add, *p)
@@ -52,14 +52,14 @@ def check_datetimelib_subtract(
52
52
  Tuple[date, timedelta],
53
53
  Tuple[datetime, timedelta],
54
54
  Tuple[datetime, datetime],
55
- ]
55
+ ],
56
56
  ) -> ResultComparison:
57
57
  """post: _"""
58
58
  return compare_results(operator.sub, *p)
59
59
 
60
60
 
61
61
  def check_datetimelib_str(
62
- obj: Union[timedelta, timezone, date, time, datetime]
62
+ obj: Union[timedelta, timezone, date, time, datetime],
63
63
  ) -> ResultComparison:
64
64
  """post: _"""
65
65
  return compare_results(_invoker("__str__"), obj)
@@ -67,7 +67,7 @@ def check_datetimelib_str(
67
67
 
68
68
  def check_datetimelib_repr(
69
69
  # TODO: re-enable time, datetime repr checking after fixing in Python 3.11
70
- obj: Union[timedelta, timezone, date]
70
+ obj: Union[timedelta, timezone, date],
71
71
  ) -> ResultComparison:
72
72
  """post: _"""
73
73
  return compare_results(_invoker("__repr__"), obj)
@@ -25,6 +25,7 @@ class UnexpectedEndError(ChunkError):
25
25
  @dataclass
26
26
  class MidChunkError(ChunkError):
27
27
  _reason: str
28
+
28
29
  # _errlen: int = 1
29
30
  def reason(self) -> str:
30
31
  return self._reason
@@ -112,7 +113,7 @@ class StemEncoder:
112
113
  continue
113
114
  if errors == "replace":
114
115
  idx += 1
115
- parts.append("\uFFFD")
116
+ parts.append("\ufffd")
116
117
  continue
117
118
 
118
119
  # 2. Then fall back to native implementations if necessary:
@@ -132,24 +133,28 @@ class StemEncoder:
132
133
 
133
134
  def _getregentry(stem_encoder: Type[StemEncoder]):
134
135
  class StemIncrementalEncoder(codecs.BufferedIncrementalEncoder):
135
- def _buffer_encode(self, input: str, errors: str, final: bool) -> bytes:
136
+ def _buffer_encode(
137
+ self, input: str, errors: str, final: bool
138
+ ) -> Tuple[bytes, int]:
136
139
  enc_name = stem_encoder.encoding_name
137
140
  out, idx, err = stem_encoder._encode_chunk(input, 0)
138
141
  assert isinstance(out, bytes)
139
142
  if not err:
140
- return out
143
+ return (out, idx)
141
144
  if isinstance(err, UnexpectedEndError) or not final:
142
- return out
145
+ return (out, idx)
143
146
  exc = UnicodeEncodeError(enc_name, input, idx, idx + 1, err.reason())
144
147
  replacement, idx = codecs.lookup_error(errors)(exc)
145
148
  if isinstance(replacement, str):
146
149
  replacement = codecs.encode(replacement, enc_name)
147
- return out + replacement
150
+ return (out + replacement, idx)
148
151
 
149
152
  class StemIncrementalDecoder(codecs.BufferedIncrementalDecoder):
150
153
  def _buffer_decode(
151
- self, input: bytes, errors: str, final: bool
154
+ self, input: Buffer, errors: str, final: bool
152
155
  ) -> Tuple[str, int]:
156
+ if not isinstance(input, bytes):
157
+ input = memoryview(input).tobytes()
153
158
  enc_name = stem_encoder.encoding_name
154
159
  out, idx, err = stem_encoder._decode_chunk(input, 0)
155
160
  assert isinstance(out, str)
@@ -7,7 +7,7 @@ from unicodedata import category
7
7
  if sys.version_info < (3, 11):
8
8
  import sre_parse as re_parser
9
9
  else:
10
- import re._parser as re_parser
10
+ import re._parser as re_parser # type: ignore
11
11
 
12
12
  from sys import maxunicode
13
13
  from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union, cast
@@ -11,7 +11,7 @@ def test_numeric():
11
11
  with standalone_statespace as space:
12
12
  with NoTracing():
13
13
  fourstr = LazyIntSymbolicStr(list(map(ord, "4")))
14
- halfstr = LazyIntSymbolicStr(list(map(ord, "\u00BD"))) # (1/2 character)
14
+ halfstr = LazyIntSymbolicStr(list(map(ord, "\u00bd"))) # (1/2 character)
15
15
  four = unicodedata.numeric(fourstr)
16
16
  half = unicodedata.numeric(halfstr)
17
17
  assert type(four) is float
@@ -22,7 +22,7 @@ def test_numeric():
22
22
  def test_decimal():
23
23
  with standalone_statespace as space:
24
24
  with NoTracing():
25
- thai4 = LazyIntSymbolicStr(list(map(ord, "\u0E54"))) # (Thai numerial 4)
25
+ thai4 = LazyIntSymbolicStr(list(map(ord, "\u0e54"))) # (Thai numerial 4)
26
26
  super4 = LazyIntSymbolicStr(list(map(ord, "\u2074"))) # (superscript 4)
27
27
  four = unicodedata.decimal(thai4)
28
28
  assert type(four) is int
@@ -34,7 +34,7 @@ def test_decimal():
34
34
  def test_digit():
35
35
  with standalone_statespace as space:
36
36
  with NoTracing():
37
- thai4 = LazyIntSymbolicStr(list(map(ord, "\u0E54"))) # (Thai numerial 4)
37
+ thai4 = LazyIntSymbolicStr(list(map(ord, "\u0e54"))) # (Thai numerial 4)
38
38
  super4 = LazyIntSymbolicStr(list(map(ord, "\u2074"))) # (superscript 4)
39
39
  four = unicodedata.digit(thai4)
40
40
  assert type(four) is int
crosshair/main.py CHANGED
@@ -774,9 +774,11 @@ def cover(
774
774
  ctxfn,
775
775
  options,
776
776
  args.coverage_type,
777
- arg_formatter=format_boundargs_as_dictionary
778
- if example_output_format == ExampleOutputFormat.ARG_DICTIONARY
779
- else format_boundargs,
777
+ arg_formatter=(
778
+ format_boundargs_as_dictionary
779
+ if example_output_format == ExampleOutputFormat.ARG_DICTIONARY
780
+ else format_boundargs
781
+ ),
780
782
  )
781
783
  except NotDeterministic:
782
784
  print(
@@ -7,7 +7,7 @@ from sys import version_info
7
7
  from types import CodeType, FrameType
8
8
  from typing import Any, Callable, Iterable, List, Mapping, Tuple, Union
9
9
 
10
- from z3 import ExprRef
10
+ from z3 import ExprRef # type: ignore
11
11
 
12
12
  from crosshair.core import (
13
13
  ATOMIC_IMMUTABLE_TYPES,
@@ -55,6 +55,7 @@ TO_BOOL = dis.opmap.get("TO_BOOL", 256)
55
55
  IS_OP = dis.opmap.get("IS_OP", 256)
56
56
  BINARY_MODULO = dis.opmap.get("BINARY_MODULO", 256)
57
57
  BINARY_OP = dis.opmap.get("BINARY_OP", 256)
58
+ LOAD_COMMON_CONSTANT = dis.opmap.get("LOAD_COMMON_CONSTANT", 256)
58
59
 
59
60
 
60
61
  def frame_op_arg(frame):
@@ -152,6 +153,39 @@ class MultiSubscriptableContainer:
152
153
  raise IndexError # (f"Index {key} out of range for list/tuple of length {len(container)}")
153
154
 
154
155
 
156
+ class LoadCommonConstantInterceptor(TracingModule):
157
+ """
158
+ As of 3.14, the bytecode generation process generates optimizations
159
+ for builtins.any/all when invoked on a generator expression.
160
+ It essentially "inlines" the logic as bytecode.
161
+ We need to avoid this.
162
+ Before entering the optimized code path, it will check that the any/all
163
+ function is identity-equal to the original builtin, which is loaded using
164
+ the LOAD_COMMON_CONSTANT opcode.
165
+
166
+ This interceptor replaces that function with a proxy that functions
167
+ identically but is not identity-equal (so that we avoid the optimized
168
+ path),
169
+ """
170
+
171
+ opcodes_wanted = frozenset([LOAD_COMMON_CONSTANT])
172
+
173
+ def trace_op(self, frame, codeobj, codenum):
174
+ CONSTANT_BUILTIN_ALL = 3
175
+ CONSTANT_BUILTIN_ANY = 4
176
+ index = frame_op_arg(frame)
177
+
178
+ def post_op():
179
+ expected_fn = all if index == CONSTANT_BUILTIN_ALL else any
180
+ if CROSSHAIR_EXTRA_ASSERTS:
181
+ if frame_stack_read(frame, -1) is not expected_fn:
182
+ raise CrossHairInternal
183
+ frame_stack_write(frame, -1, lambda *a: expected_fn(*a))
184
+
185
+ if index == CONSTANT_BUILTIN_ALL or index == CONSTANT_BUILTIN_ANY:
186
+ COMPOSITE_TRACER.set_postop_callback(post_op, frame)
187
+
188
+
155
189
  class SymbolicSubscriptInterceptor(TracingModule):
156
190
  opcodes_wanted = frozenset([BINARY_SUBSCR, BINARY_OP])
157
191
 
@@ -554,6 +588,8 @@ def make_registrations():
554
588
  register_opcode_patch(SymbolicSliceInterceptor())
555
589
  if sys.version_info < (3, 9):
556
590
  register_opcode_patch(ComparisonInterceptForwarder())
591
+ if sys.version_info >= (3, 14):
592
+ register_opcode_patch(LoadCommonConstantInterceptor())
557
593
  register_opcode_patch(ContainmentInterceptor())
558
594
  register_opcode_patch(BuildStringInterceptor())
559
595
  register_opcode_patch(FormatValueInterceptor())
@@ -2,7 +2,7 @@ import math
2
2
  from collections import defaultdict
3
3
  from typing import Counter, Dict, List, Optional, Sequence, Tuple
4
4
 
5
- from z3 import ExprRef
5
+ from z3 import ExprRef # type: ignore
6
6
 
7
7
  from crosshair.statespace import (
8
8
  AbstractPathingOracle,
@@ -1,6 +1,6 @@
1
1
  import random
2
2
 
3
- import z3
3
+ import z3 # type: ignore
4
4
 
5
5
  from crosshair.pathing_oracle import ConstrainedOracle, PreferNegativeOracle
6
6
  from crosshair.statespace import RootNode, SimpleStateSpace, WorstResultNode
@@ -1,4 +1,5 @@
1
1
  """API for registering contracts for external libraries."""
2
+
2
3
  from dataclasses import dataclass
3
4
  from inspect import Parameter, Signature, getmodule, ismethod, signature
4
5
  from types import MethodDescriptorType, ModuleType, WrapperDescriptorType
@@ -99,12 +99,10 @@ def test_register_numpy_randint():
99
99
 
100
100
  def test_register_overload():
101
101
  @overload
102
- def overld(a: int) -> int:
103
- ...
102
+ def overld(a: int) -> int: ...
104
103
 
105
104
  @overload
106
- def overld(a: str) -> str:
107
- ...
105
+ def overld(a: str) -> str: ...
108
106
 
109
107
  def overld(a: Union[int, str]) -> Union[int, str]:
110
108
  if isinstance(a, int):
@@ -38,10 +38,10 @@ class MapBase(collections.abc.MutableMapping):
38
38
  return NotImplemented
39
39
  if len(self) != len(other):
40
40
  return False
41
- for (k, self_value) in self.items():
41
+ for k, self_value in self.items():
42
42
  found = False
43
43
  # We do a slow nested loop search because we don't want to hash the key.
44
- for (other_key, other_value) in other.items():
44
+ for other_key, other_value in other.items():
45
45
  if other_key != k:
46
46
  continue
47
47
  if self_value == other_value:
@@ -122,7 +122,7 @@ class SimpleDict(MapBase):
122
122
  def __getitem__(self, key, default=_MISSING):
123
123
  if not is_hashable(key):
124
124
  raise TypeError("unhashable type")
125
- for (k, v) in self.contents_:
125
+ for k, v in self.contents_:
126
126
  # Note that the identity check below is not just an optimization;
127
127
  # it is required to implement the semantics of NaN dict keys
128
128
  if k is key or k == key:
@@ -134,7 +134,7 @@ class SimpleDict(MapBase):
134
134
  def __setitem__(self, key, value):
135
135
  if not is_hashable(key):
136
136
  raise TypeError("unhashable type")
137
- for (i, (k, v)) in enumerate(self.contents_):
137
+ for i, (k, v) in enumerate(self.contents_):
138
138
  if k == key:
139
139
  self.contents_[i] = (k, value)
140
140
  return
@@ -143,7 +143,7 @@ class SimpleDict(MapBase):
143
143
  def __delitem__(self, key):
144
144
  if not is_hashable(key):
145
145
  raise TypeError("unhashable type")
146
- for (i, (k, v)) in enumerate(self.contents_):
146
+ for i, (k, v) in enumerate(self.contents_):
147
147
  if k == key:
148
148
  del self.contents_[i]
149
149
  return
@@ -493,9 +493,11 @@ class SequenceConcatenation(collections.abc.Sequence, SeqBase):
493
493
  return second.__getitem__(
494
494
  slice(
495
495
  i.start - firstlen,
496
- i.stop
497
- if i.stop is None or i.stop < 0
498
- else i.stop - firstlen,
496
+ (
497
+ i.stop
498
+ if i.stop is None or i.stop < 0
499
+ else i.stop - firstlen
500
+ ),
499
501
  i.step,
500
502
  )
501
503
  )
crosshair/statespace.py CHANGED
@@ -1018,7 +1018,7 @@ class StateSpace:
1018
1018
  ) -> object:
1019
1019
  with NoTracing():
1020
1020
  # TODO: needs more testing
1021
- for (curref, curtyp, curval) in self.heaps[snapshot]:
1021
+ for curref, curtyp, curval in self.heaps[snapshot]:
1022
1022
 
1023
1023
  # TODO: using unify() is almost certainly wrong; just because the types
1024
1024
  # have some instances in common does not mean that `curval` actually
@@ -107,7 +107,7 @@ def divide_stdlib_module(
107
107
  modulename: str, items: list[tuple[str, str, str]]
108
108
  ) -> dict[str, list[tuple[str, str, str]]]:
109
109
  ret = defaultdict(list)
110
- for (name, color, src) in items:
110
+ for name, color, src in items:
111
111
  if name.endswith("_method"):
112
112
  name = name.removesuffix("_method")
113
113
  (classname, methodname) = name.split("_", 1)
@@ -120,7 +120,7 @@ def divide_stdlib_module(
120
120
 
121
121
 
122
122
  stdlib = {}
123
- for (modulename, items) in stdlib_demos().items():
123
+ for modulename, items in stdlib_demos().items():
124
124
  stdlib[modulename] = divide_stdlib_module(modulename, items)
125
125
 
126
126
 
crosshair/tracers.py CHANGED
@@ -156,12 +156,14 @@ _CALL_HANDLERS: Dict[int, Callable[[object], CallStackInfo]] = {
156
156
  CALL_KW: handle_call_kw,
157
157
  CALL_FUNCTION: handle_call_function,
158
158
  CALL_FUNCTION_KW: handle_call_function_kw,
159
- CALL_FUNCTION_EX: handle_call_function_ex_3_14
160
- if sys.version_info >= (3, 14)
161
- else (
162
- handle_call_function_ex_3_13
163
- if sys.version_info >= (3, 13)
164
- else handle_call_function_ex_3_6
159
+ CALL_FUNCTION_EX: (
160
+ handle_call_function_ex_3_14
161
+ if sys.version_info >= (3, 14)
162
+ else (
163
+ handle_call_function_ex_3_13
164
+ if sys.version_info >= (3, 13)
165
+ else handle_call_function_ex_3_6
166
+ )
165
167
  ),
166
168
  CALL_METHOD: handle_call_method,
167
169
  }
crosshair/util.py CHANGED
@@ -368,7 +368,7 @@ def format_boundargs_as_dictionary(bound_args: BoundArguments) -> str:
368
368
 
369
369
  def format_boundargs(bound_args: BoundArguments) -> str:
370
370
  arg_strings: List[str] = []
371
- for (name, param) in bound_args.signature.parameters.items():
371
+ for name, param in bound_args.signature.parameters.items():
372
372
  param_kind = param.kind
373
373
  vals = bound_args.arguments.get(name, param.default)
374
374
  if param_kind == Parameter.VAR_POSITIONAL:
@@ -503,9 +503,9 @@ class EvalFriendlyReprContext:
503
503
  oid = id(obj)
504
504
  typ = type(obj)
505
505
  if obj in instance_overrides:
506
- repr_fn: Callable[
507
- [Any], Union[str, ReferencedIdentifier]
508
- ] = instance_overrides[obj]
506
+ repr_fn: Callable[[Any], Union[str, ReferencedIdentifier]] = (
507
+ instance_overrides[obj]
508
+ )
509
509
  elif typ == float:
510
510
  if math.isfinite(obj):
511
511
  repr_fn = repr
@@ -543,7 +543,7 @@ class EvalFriendlyReprContext:
543
543
  counts = collections.Counter(re.compile(r"\b_ch_efr_\d+_\b").findall(output))
544
544
  assignment_remaps = {}
545
545
  nextvarnum = 1
546
- for (varname, count) in counts.items():
546
+ for varname, count in counts.items():
547
547
  if count > 1:
548
548
  assignment_remaps[varname + ":="] = f"v{nextvarnum}:="
549
549
  assignment_remaps[varname] = f"v{nextvarnum}"
@@ -625,7 +625,7 @@ class DynamicScopeVar(Generic[_T]):
625
625
 
626
626
  class AttributeHolder:
627
627
  def __init__(self, attrs: Mapping[str, object]):
628
- for (k, v) in attrs.items():
628
+ for k, v in attrs.items():
629
629
  self.__dict__[k] = v
630
630
 
631
631
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crosshair-tool
3
- Version: 0.0.96
3
+ Version: 0.0.97
4
4
  Summary: Analyze Python code for correctness using symbolic execution.
5
5
  Home-page: https://github.com/pschanely/CrossHair
6
6
  Author: Phillip Schanely
@@ -8,7 +8,6 @@ Author-email: pschanely+vE7F@gmail.com
8
8
  License: MIT
9
9
  Classifier: Development Status :: 3 - Alpha
10
10
  Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: MIT License
12
11
  Classifier: Operating System :: OS Independent
13
12
  Classifier: Programming Language :: Python :: 3
14
13
  Classifier: Programming Language :: Python :: 3.8
@@ -32,11 +31,11 @@ Requires-Dist: pygls >=1.0.0
32
31
  Requires-Dist: typeshed-client >=2.0.5
33
32
  Provides-Extra: dev
34
33
  Requires-Dist: autodocsumm <1,>=0.2.2 ; extra == 'dev'
35
- Requires-Dist: black ==22.3.0 ; extra == 'dev'
34
+ Requires-Dist: black ==25.9.0 ; extra == 'dev'
36
35
  Requires-Dist: deal >=4.13.0 ; extra == 'dev'
37
36
  Requires-Dist: icontract >=2.4.0 ; extra == 'dev'
38
37
  Requires-Dist: isort ==5.11.5 ; extra == 'dev'
39
- Requires-Dist: mypy ==0.990 ; extra == 'dev'
38
+ Requires-Dist: mypy ==1.18.1 ; extra == 'dev'
40
39
  Requires-Dist: pre-commit ~=2.20 ; extra == 'dev'
41
40
  Requires-Dist: pytest ; extra == 'dev'
42
41
  Requires-Dist: pytest-xdist ; extra == 'dev'
@@ -47,7 +46,7 @@ Requires-Dist: rst2pdf >=0.102 ; extra == 'dev'
47
46
  Requires-Dist: z3-solver ==4.14.1.0 ; extra == 'dev'
48
47
  Requires-Dist: numpy ==1.23.4 ; (python_version < "3.12") and extra == 'dev'
49
48
  Requires-Dist: numpy ==1.26.0 ; (python_version >= "3.12" and python_version < "3.13") and extra == 'dev'
50
- Requires-Dist: numpy ==2.0.1 ; (python_version >= "3.13") and extra == 'dev'
49
+ Requires-Dist: numpy ==2.3.3 ; (python_version >= "3.13") and extra == 'dev'
51
50
 
52
51
  <img src="https://raw.githubusercontent.com/pschanely/CrossHair/main/doc/source/logo-gray.png" width="5%" align="left">
53
52
 
@@ -1,41 +1,41 @@
1
- _crosshair_tracers.cpython-38-x86_64-linux-gnu.so,sha256=I2PQ2mjtjrfVX3uIISbP3TZ2i1ZIigIgZIWJxRFSX2Q,75984
2
- crosshair/__init__.py,sha256=pX7dpKGv0frAXPUfHUH9_8CmbQ0ItGRkG9yPi7_uApI,936
1
+ _crosshair_tracers.cpython-38-x86_64-linux-gnu.so,sha256=k_rm2aJb1mXqYIilwqysifTcVghysISH9J3crK1D7-4,75984
2
+ crosshair/__init__.py,sha256=7ph2S2-0_w1V5foTkyDqlkF63lSBFZ_QR10iQNgoKH0,936
3
3
  crosshair/__main__.py,sha256=zw9Ylf8v2fGocE57o4FqvD0lc7U4Ld2GbeCGxRWrpqo,252
4
4
  crosshair/_mark_stacks.h,sha256=j86qubOUvVhoR19d74iQ084RrTEq8M6oT4wJsGQUySY,28678
5
5
  crosshair/_preliminaries_test.py,sha256=r2PohNNMfIkDqsnvI6gKlJTbwBaZA9NQJueQfJMN2Eo,504
6
6
  crosshair/_tracers.h,sha256=QFBklLqMWmIpUzBIn_A4SKdpjwHs-N7ttx-F5jtWWCQ,2174
7
7
  crosshair/_tracers_pycompat.h,sha256=6IYnbQxrYkhBsLDAHSX25DPOwo1oYHCZUVWZ8c7YCnQ,14356
8
- crosshair/_tracers_test.py,sha256=KpCGspjOUeZuhwTYgn_RxI4M4wMbT5rldusFDgneQ6M,3596
8
+ crosshair/_tracers_test.py,sha256=7rrK0djASmRAlWcH4SiJqrWN7hk3oB_rYwhUG4gjxm4,3645
9
9
  crosshair/abcstring.py,sha256=ROU8LzS7kfEU2L_D3QfhVxIjrYr1VctwUWfylC7KlCc,6549
10
10
  crosshair/auditwall.py,sha256=sqOmfXQLgmGfWS7b8SmVv66eFM2owaGn-4Ppq453VLI,5138
11
11
  crosshair/auditwall_test.py,sha256=VPcw_OW3nl3BkOZY4wEEtVDyTamdgqD4IjRccI2p5vI,2030
12
- crosshair/codeconfig.py,sha256=GgF-ND8Ha3FysSTQ-JuezHjlhGVBbo5aCJov1Ps3VSE,3959
12
+ crosshair/codeconfig.py,sha256=TaIdOKxykpk6YeTtO_Xwsa3IDBTP6g3UGkFBt0PTDR4,3959
13
13
  crosshair/codeconfig_test.py,sha256=RnC-RnNpr6If4eHmOepDZ33MCmfyhup08dzHKCm5xWA,3350
14
- crosshair/condition_parser.py,sha256=oquaht026eZUigh2lyaFLXYDbmENdBKjddszx0a-B3w,42647
14
+ crosshair/condition_parser.py,sha256=C7S_IogPTDSB-NPGRgJ_CzuWF9YCzGsm6mc37VBo6lY,42684
15
15
  crosshair/condition_parser_test.py,sha256=UcgxzqrBLUMScif_RrgHvrhjzWx1KUPgAQOEmfJw7lc,15500
16
16
  crosshair/conftest.py,sha256=BkLszApkdy6FrvzaHO7xh8_BJrG9AfytFTse-HuQVvg,653
17
17
  crosshair/copyext.py,sha256=GBGQP9YAHoezLXwb_M59Hh1VXSou5EQt4ZmmUA0T_og,4899
18
18
  crosshair/copyext_test.py,sha256=uJzdC9m2FqMjqQ-ITFoP0MZg3OCiO8paU-d533KocD8,2108
19
- crosshair/core.py,sha256=nUdmPCcEWxaYawkydj2AJ7VdXe8IIu7hVyDi83Bxwec,64262
19
+ crosshair/core.py,sha256=HqelePQQYES9SS36qR9mGEEeKcvEFrIHGg-8OG5i-Kg,64252
20
20
  crosshair/core_and_libs.py,sha256=8FGL62GnyX6WHOqKh0rqJ0aJ_He5pwZm_zwPXTaPqhI,3963
21
21
  crosshair/core_regestered_types_test.py,sha256=er3ianvu-l0RS-WrS46jmOWr4Jq06Cec9htAXGXJSNg,2099
22
22
  crosshair/core_test.py,sha256=P-r-qzHPZ2yLmSBZByYPccJZfxYi2ZCwn9o1mEfzRe8,33019
23
23
  crosshair/diff_behavior.py,sha256=_5X_pTN0_-rSPrh8dfpODJG_phFMn7fWc-_zLgO3UTk,11253
24
24
  crosshair/diff_behavior_test.py,sha256=nCpzOjrw0qsYgVhD2iCvKiNAt82SrfUWxWS5mPSE73w,7215
25
- crosshair/dynamic_typing.py,sha256=ANq42kxSQ5B0STZF3uwOEys_fLCj20cMCCcBH6dbXWo,12758
25
+ crosshair/dynamic_typing.py,sha256=JMcEX5HMMm9u0_lLtZI1jrAw9HGZqXyq8IYGQP4KYSc,12752
26
26
  crosshair/dynamic_typing_test.py,sha256=8p4NOJ6i9q9mozgCYlZP3VCs-TFMDaE_7W-TyNEse4o,5907
27
- crosshair/enforce.py,sha256=FsZx3D-KtGrhb8xdAZbPUtwvVmEu8IAn7rwf7tmkrRY,10010
27
+ crosshair/enforce.py,sha256=YVze7uYfR_bM1jUvDlU-8cF4cphRRfe78exNZ1xXtuI,10011
28
28
  crosshair/enforce_test.py,sha256=C6CQ4P1FjkdIJeJg3aJynp1iLDCE6BFCEVtSqXbvmQk,4665
29
- crosshair/fnutil.py,sha256=X80bD2Lh4QAh-rF561r3JRxjxcuZepF3hJaxaj1GG9s,13123
30
- crosshair/fnutil_test.py,sha256=wXtfIxAupRm0KUzKob8luEsNI4YegBQUfwz7msWbfHY,2186
31
- crosshair/fuzz_core_test.py,sha256=q7WsZt6bj5OJrXaVsT3JaRYWWnL8X_1flSfty4Z7CcA,16903
29
+ crosshair/fnutil.py,sha256=Xs0xJPcQm0z3tWQDjd_I-ainWHTxcT61dv8A3CY3--8,13109
30
+ crosshair/fnutil_test.py,sha256=cLHJ9uhQf797sTxuh4BGgQ0Fo5rcQFStkiPbzQPhIXA,2091
31
+ crosshair/fuzz_core_test.py,sha256=bLzdHBROzX3P3cfBeDTY9bJbfhe-CCoeLOF4Mt31wm0,17443
32
32
  crosshair/lsp_server.py,sha256=j7SX4pdVwa2MrtkNIjajLilzl5CZTY6PrBQsa26cdNo,8670
33
33
  crosshair/lsp_server_test.py,sha256=7LO1Qqxkper3Xt2krgOlGqF1O_uDObo76o4FZbIqykY,969
34
- crosshair/main.py,sha256=TkaOr39tMV9ZHQXgfJobKFEVW60XpHUqdY520nMIWw8,34659
34
+ crosshair/main.py,sha256=CY3PBcis302n0KvqoyDDoqtthNL4XASXHssO1I7DkJM,34707
35
35
  crosshair/main_test.py,sha256=2xpgNqog__XcYffGcwPeEEmr0Vy4EgVZE8GCAjQnE8U,14834
36
36
  crosshair/objectproxy.py,sha256=1cO_ApA0AKPfCRu6MIsxUOKUUEGn0b1U4IHxTC4nDGI,9790
37
37
  crosshair/objectproxy_test.py,sha256=UJuO_jUt8_OEUtgQWyhlekPOdvtM8IQ5M9I_1AqXPWM,1081
38
- crosshair/opcode_intercept.py,sha256=ZNePiOMX5xmREkA-x2t1MuM8fmHPbaogMOmGYn21NzU,21579
38
+ crosshair/opcode_intercept.py,sha256=atmnEDG9oDP0zlkGjJRAsYhD0Aw_PORf4coZZz2JgWw,23060
39
39
  crosshair/opcode_intercept_test.py,sha256=Si3rJQR5cs5d4uB8uwE2K8MjP8rE1a4yHkjXzhfS10A,9241
40
40
  crosshair/options.py,sha256=htQNgnrpoRjSNq6rfLBAF8nos-NNIwmP6tQYyI8ugsM,6775
41
41
  crosshair/options_test.py,sha256=lzA-XtwEwQPa4wV1wwhCRKhyLOvIhThU9WK5QRaRbxQ,379
@@ -44,36 +44,36 @@ crosshair/path_cover.py,sha256=TCofZ9D5q7hpEIOnifp53BvY_YyPpZZC-heZw_NuTOQ,6838
44
44
  crosshair/path_cover_test.py,sha256=U46zw4-m7yAXhu8-3Xnhvf-_9Ov5ivfCAm5euGwpRFA,4089
45
45
  crosshair/path_search.py,sha256=wwZjp-3E4dENnJa6BlnSq8FARkIx0PyUYc7kvH32A2k,5588
46
46
  crosshair/path_search_test.py,sha256=7cqzAMXUYAtA00mq9XR5AaZChqeQyXyCfuuv53_51pk,1692
47
- crosshair/pathing_oracle.py,sha256=PvqX7396SaQK3m-bMpCwBKmHW9SYiioooUWNvmmEqNw,10497
48
- crosshair/pathing_oracle_test.py,sha256=-6U-n1k6MahHYnQ6lvI9ahFjPr9vUfaUAnFThXR2k78,709
47
+ crosshair/pathing_oracle.py,sha256=qa-_OlyuCHpNHkK5xN8OvxRgOEOA56VpGf0jUIR8L-M,10513
48
+ crosshair/pathing_oracle_test.py,sha256=6k9-8kAbTFUvxhEKSE5NPntEW2qMWkQi4zac_U1kYxY,725
49
49
  crosshair/pure_importer.py,sha256=-t4eowrZOQmfqK1N2tjI5POoaxRGavytwMmbRivelFg,878
50
50
  crosshair/pure_importer_test.py,sha256=Xjtlwn1mj7g-6VA87lrvzfUADCjlmn1wgHtbrnc0uuY,421
51
51
  crosshair/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
- crosshair/register_contract.py,sha256=EnDAxngJhKvJLFdw5kVgqaYDQ5hAZXKwAGBdXpot-AQ,10386
53
- crosshair/register_contract_test.py,sha256=DhvKIcF3LgQfHfUSCccoA11ctCdFaQR263Pc4YUuxyk,4970
54
- crosshair/simplestructs.py,sha256=CiZSuHH_j_bYitaW-n7vWd_42xSyV6Jh8es3BQLlcHk,34221
52
+ crosshair/register_contract.py,sha256=4p99KAUhu1k-OctIT6WX2YFbVaMCV6BDEULNvQFONGE,10387
53
+ crosshair/register_contract_test.py,sha256=9AWv9psiAredvcOlK2_pBpsgwIgBbecWyKEEvWiWBSI,4954
54
+ crosshair/simplestructs.py,sha256=O236XDO0dWGM59jktMUp5RG9xYY5iqZV219DknKAXgc,34283
55
55
  crosshair/simplestructs_test.py,sha256=6uDdrSISHLhwnFuESkR8mUGw7m1llM6vCNDFChkfSs8,8639
56
56
  crosshair/smtlib.py,sha256=hh-P32KHoH9BCq3oDYGp2PfOeOb8CwDj8tTkgqroLD8,689
57
57
  crosshair/smtlib_test.py,sha256=edzEn19u2YYHxSzG9RrMiu2HTiEexAuehC3IlG9LuJM,511
58
- crosshair/statespace.py,sha256=h1un79C-vkyKJ1iLAU4lQlVu3A6YqqbpcrqHGCsTsrg,43442
58
+ crosshair/statespace.py,sha256=D0Bptt3KMPG8RDzq_numy51sK1Pu_6QqcGKGfXC37s8,43440
59
59
  crosshair/statespace_test.py,sha256=Eq7LNpjradHyCoCKU91Fxmo9DUpK2Mk4PyxxiAEp-Yk,3211
60
60
  crosshair/stubs_parser.py,sha256=rlBTQus5BlZ3Ygg6Xzk5dbQbDtRpv6w9i2HQmGrPVmc,14240
61
61
  crosshair/stubs_parser_test.py,sha256=0itTT0Udul_51RJXNv6KB97z44gYze6NZfKJL7yIDzA,1228
62
62
  crosshair/test_util.py,sha256=D9-f-DdzJemfAUkQL0cwKxPL8RZ-5gkVmghyRcKlBJI,10367
63
63
  crosshair/test_util_test.py,sha256=_r8DtAI5b1Yn1ruv9o51FWHmARII3-WDkWWnnY1iaAw,943
64
- crosshair/tracers.py,sha256=_jaSDgZ_pYdqacWE_msXn7W7CoSdQ_-7hlrxa891oHo,17139
64
+ crosshair/tracers.py,sha256=UX-JKKjggQ0_EDh0AGNf4b_2ku9SD9pWgRyFcJDAVpc,17179
65
65
  crosshair/tracers_test.py,sha256=EBK_ZCy2MsxqmEaGjo0uw9zAztW9O6fhCW_0PJxyTS8,3270
66
66
  crosshair/type_repo.py,sha256=x_eK-YlcHv_dxDKy6m7ty0zNO6y058o3r6QJ55RcG3s,4664
67
67
  crosshair/unicode_categories.py,sha256=g4pnUPanx8KkpwI06ZUGx8GR8Myruf_EpTjyti_V4z8,333519
68
68
  crosshair/unicode_categories_test.py,sha256=ZAU37IDGm9PDvwy_CGFcrF9Waa8JuUNdI4aq74wkB6c,739
69
- crosshair/util.py,sha256=sIfaKFvNHR5w5VCno2d15d_LyfwoewKqRzJ_3ZNV-Vc,22218
69
+ crosshair/util.py,sha256=pfBTBNhqMuaoUvAaFZal4LqVEMzWlzmcobHTxp_ZrlE,22214
70
70
  crosshair/util_test.py,sha256=_KTQ0O4cLhF1pAeB8Y8Cyqbd0UyZf5KxJUaiA-ew-tE,4676
71
71
  crosshair/watcher.py,sha256=kCCMlLe2KhW5MbEbMmixNRjRAvu5CypIAGd1V_YZ9QM,10048
72
72
  crosshair/watcher_test.py,sha256=Ef1YSwy68wWPR5nPjwvEKPqxltI9pE9lTbnesmDy3Bk,2764
73
73
  crosshair/z3util.py,sha256=AkslxCSfzgSni6oWXUckWihWn3LuceQycR0X3D3ZhD8,1759
74
74
  crosshair/z3util_test.py,sha256=CZovn4S9mYcG_yQegcxm80VHrvUdvNei0gvGTF9TOrk,173
75
75
  crosshair/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
- crosshair/examples/check_examples_test.py,sha256=pFZRUi_yubIOaIZ_n7KkrG_qCKyHZnzcL5_y0NFqZKM,4062
76
+ crosshair/examples/check_examples_test.py,sha256=ieB2KBBPReQBOr5-AZCgrVyhN1YXGYyQMjHyQBQ4zTI,4063
77
77
  crosshair/examples/PEP316/__init__.py,sha256=LdmvJx2cbzC3iip3NwtT0Ds2v99l3KXl1q9Kc0TmCWE,34
78
78
  crosshair/examples/PEP316/bugs_detected/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
79
  crosshair/examples/PEP316/bugs_detected/getattr_magic.py,sha256=vZ6pWnBsSE641rzNx55iB8lLOI4zB0nXkUU1WxtD0RI,319
@@ -96,14 +96,14 @@ crosshair/examples/icontract/correct_code/__init__.py,sha256=47DEQpj8HBSa-_TImW-
96
96
  crosshair/examples/icontract/correct_code/arith.py,sha256=ZSwsotmq_l1Mp3dOgjcRJsMher8IILYdi99JuuDdZWc,1508
97
97
  crosshair/examples/icontract/correct_code/showcase.py,sha256=WUqZUOUTl58JBoDxenee9GMV5NaI_pby5NG-jeVv1z4,3087
98
98
  crosshair/libimpl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
- crosshair/libimpl/arraylib.py,sha256=vW0lvkYJx8B3hLnhwXhCc-ZwtWtEwZFLm7T8ahrrKgs,4877
99
+ crosshair/libimpl/arraylib.py,sha256=QL6QH9iHHsmKA2zzW9DKPB6AbaxRiZbD3ikSGQVgqxU,4875
100
100
  crosshair/libimpl/binascii_ch_test.py,sha256=hFqSfF1Q8jl2LNBIWaQ6vBJIIshPOmSwrR0T1Ko4Leo,1009
101
101
  crosshair/libimpl/binascii_test.py,sha256=LOBqLAJ77Kx8vorjVTaT3X0Z93zw4P5BvwUapMCiSLg,1970
102
102
  crosshair/libimpl/binasciilib.py,sha256=9w4C37uxRNOmz9EUuhJduHlMKn0f7baY5fwwdvx1uto,5070
103
103
  crosshair/libimpl/bisectlib_test.py,sha256=ZQtYmBYD0Pb1IiFelsgdvqyeUMKaqaDb1BRb87LTSbI,753
104
- crosshair/libimpl/builtinslib.py,sha256=j275QUgWqnq62immbBqUzlPesOq0t-oTb0C9WL7sIiA,173276
105
- crosshair/libimpl/builtinslib_ch_test.py,sha256=Fyu2fZLXI-pUaS3gyyM6zMQhsTFdpRCnnp1rXwxKXwk,30854
106
- crosshair/libimpl/builtinslib_test.py,sha256=jbN2t-zteWqF5TxA7oo4c9UsPrqklBY7wlEt16rxqtI,92230
104
+ crosshair/libimpl/builtinslib.py,sha256=R6w3t-i1uJ3U8R-qHtrktZRTFm_K4SD0LjfeWBZbBDw,173362
105
+ crosshair/libimpl/builtinslib_ch_test.py,sha256=UasixDc_qZHOEkmMkh_2r9l2NgItQBzwHpvs7dRfgvk,30857
106
+ crosshair/libimpl/builtinslib_test.py,sha256=LYjvmVx0ndUK7YNMzNUaH39YesY_yrvIWb5XOwdnkDM,92255
107
107
  crosshair/libimpl/codecslib.py,sha256=lB87T1EYSBh4JXaqzjSpQG9CMfKtgckwA7f6OIR0S-Q,2668
108
108
  crosshair/libimpl/codecslib_test.py,sha256=8K64njhxnTe7qLh-_onARNsm_qSG7BWM5dXgADYi54A,2536
109
109
  crosshair/libimpl/collectionslib.py,sha256=VuDIOUOGORiUT9J0tDVECr6oC-yUR3WAiFnMeVGzi-o,8583
@@ -111,8 +111,8 @@ crosshair/libimpl/collectionslib_ch_test.py,sha256=PYitnmXXEZfm25FzBodEX1hOpwqnD
111
111
  crosshair/libimpl/collectionslib_test.py,sha256=0qmCRQbxfX8vMZLaok1GS68NIocR--RyTVVDqbtHalU,9185
112
112
  crosshair/libimpl/copylib.py,sha256=icHJWeFK_tsPSdJhvlS5fVcBwlh0uJh0nzXsRJCGtzs,527
113
113
  crosshair/libimpl/copylib_test.py,sha256=VpS9ICvIjzKw0kccsl1v5FB1chHHEIWdOAerEQ_pGMw,705
114
- crosshair/libimpl/datetimelib.py,sha256=kVWcoHMX-dPW-un7XoEIURfWlVOst6h_JFmjrhFiE1U,79168
115
- crosshair/libimpl/datetimelib_ch_test.py,sha256=r_V9H34a4POlEeffi46mEtVI9ek80DHaEOiCTKON9Us,9283
114
+ crosshair/libimpl/datetimelib.py,sha256=3mdouYmzY5wIbByKcx_ehvzLYasiM4LDEn1-BB9edV0,79146
115
+ crosshair/libimpl/datetimelib_ch_test.py,sha256=nevP0P8nkJ8DasvoVcD2tHiaZSFz5H8BHozzI-ZElhg,9288
116
116
  crosshair/libimpl/datetimelib_test.py,sha256=v9Cg512AXIGy7_dsN2y_ZD7W7fqfSSz07eiCUZukM60,2659
117
117
  crosshair/libimpl/decimallib.py,sha256=zBKDrDZcg45oCKUkf6SIDuVpjA1Web7tD1MEQo5cjxI,177348
118
118
  crosshair/libimpl/decimallib_ch_test.py,sha256=FVCY4KB8lJWeRKnz8txNkEc1te4QRKQYJtvXDuWfzPk,2380
@@ -144,7 +144,7 @@ crosshair/libimpl/oslib.py,sha256=GVOsJKEFoIzY9S5CRZwKH5pRsccjBbGpPOlvAm_2HtQ,12
144
144
  crosshair/libimpl/pathliblib_test.py,sha256=NDeNOI24naLcvz6Lrx51nS-JhILHJjY1JNhRQO3Lufw,252
145
145
  crosshair/libimpl/randomlib.py,sha256=loyhlbRBJEs32kKFv_1O5PxKQU47F5kCz54OaNVuzUk,6161
146
146
  crosshair/libimpl/randomlib_test.py,sha256=KuEgrih9JvstsFDwrgAuHZrlVjIvaNUxS8ftiGPrwHI,3322
147
- crosshair/libimpl/relib.py,sha256=3DhrbGqJcfpj5JNfcD8Pf4xsA4WEegxbukwgKoPLP3o,29256
147
+ crosshair/libimpl/relib.py,sha256=ahS9f1_rhbVKZUhvYmuSTv0_ovmvH5NXShxDJu7aUhE,29272
148
148
  crosshair/libimpl/relib_ch_test.py,sha256=zvSBF82mNQR5yEOMwwcaBOh8OpJkQeiVl85pgYVvJRA,5235
149
149
  crosshair/libimpl/relib_test.py,sha256=3raQ0JoU4vu8_NKfrjk7TkUIqVuuhR8mGCRPJPb0RI0,16085
150
150
  crosshair/libimpl/timelib.py,sha256=MXEFOZjFGa1-yLvmB3l3DFTLF9PSluOlmRK-ZJaA_oI,2409
@@ -152,7 +152,7 @@ crosshair/libimpl/timelib_test.py,sha256=Ercmhw1Yc96CYnWhqIW7eu31R95uTGVZcgzxSiZ
152
152
  crosshair/libimpl/typeslib.py,sha256=5qWrHZZN8jQZoHPiQtkaFolR8qTYCQtJw3HRWCrCKQI,468
153
153
  crosshair/libimpl/typeslib_test.py,sha256=qCeUU_c-zmuvfwHEsaYqic9wdGzs9XbDZNr6bF2Xp58,1129
154
154
  crosshair/libimpl/unicodedatalib.py,sha256=q5LoCaEbHJrUwVWtUrlS3n_X21yp15xTS42l-9AQ6Us,3103
155
- crosshair/libimpl/unicodedatalib_test.py,sha256=CJkAbiu8_2uhvjDIoYi3IJ8Nb_8sdjKVNvNhJCgPbZ0,1442
155
+ crosshair/libimpl/unicodedatalib_test.py,sha256=b0CHHHqDj5Ej_UEDnz3aUesILObcfLm00eEXQtfsgfM,1442
156
156
  crosshair/libimpl/urlliblib.py,sha256=EaC-nWdi-IFG3ewZrzgCqbKc9Sf9wlUN0wvGjTU5TOM,614
157
157
  crosshair/libimpl/urlliblib_test.py,sha256=UcSmwRdJFkzXvkaV-jmrP6G4zhbu7X2NNjM7ePsYxRs,503
158
158
  crosshair/libimpl/weakreflib.py,sha256=By2JxeBHJCQP_Na5MBhE9YCc0O5NoKefKASoRBUNcW0,230
@@ -160,17 +160,17 @@ crosshair/libimpl/weakreflib_test.py,sha256=CdGJhW32qJoxedn8QzPcMcKKmfl9Nv4FPDYe
160
160
  crosshair/libimpl/zliblib.py,sha256=XymJTKYbplpYJZ-P7GKVSY3V_8HPy5lqRFsCH1zezIk,357
161
161
  crosshair/libimpl/zliblib_test.py,sha256=mckg9PnZrBUTStzMzHIoZl8JPuAzsIfrEruNKNDpYiE,388
162
162
  crosshair/libimpl/encodings/__init__.py,sha256=5LTEj1M-S00eZ4rfQWczAixg57vyh_9vZ5m5EKB5Ksc,680
163
- crosshair/libimpl/encodings/_encutil.py,sha256=nwVWqcGM1f7-hAC3Z46KnfrLzAjhfy4zaTa11uVBk6M,6828
163
+ crosshair/libimpl/encodings/_encutil.py,sha256=R0tLdyc83fN6C8c_tl5vetDCpayxeYaAT7UWwPQzX10,6982
164
164
  crosshair/libimpl/encodings/ascii.py,sha256=Cz1xraTkXdQ5aBKDkorX4rAvrmf877_EqzC9hOmbItw,1416
165
165
  crosshair/libimpl/encodings/latin_1.py,sha256=ftUsPjUb9L7UKXKi9P7OAqOl9FkNP98M9jMAvseXBCQ,1242
166
166
  crosshair/libimpl/encodings/utf_8.py,sha256=BygLLIeI3_F2MpFVgaty8ebiuxp0YWz7IzXeYPWjsqU,3173
167
167
  crosshair/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
168
168
  crosshair/tools/check_help_in_doc.py,sha256=P21AH3mYrTVuBgWD6v65YXqBqmqpQDUTQeoZ10rB6TU,8235
169
169
  crosshair/tools/check_init_and_setup_coincide.py,sha256=kv61bXqKSKF_5J-kLNEhCrCPyszg7iZQWDu_Scnec98,3502
170
- crosshair/tools/generate_demo_table.py,sha256=0SeO0xQdiT-mbLNHt4rYL0wcc2DMh0v3qtzBdoQonDk,3831
171
- crosshair_tool-0.0.96.dist-info/LICENSE,sha256=NVyMvNqn1pH6RSHs6RWRcJyJvORnpgGFBlF73buqYJ0,4459
172
- crosshair_tool-0.0.96.dist-info/METADATA,sha256=UaPu-bjAbWd7htrz1n-BFz0AuNy_NtGKhZklVoNs6x8,6558
173
- crosshair_tool-0.0.96.dist-info/WHEEL,sha256=AtKzrIIwO6LyEQPNa-CKogjoLSeXFnST8-hqmpwwZQA,110
174
- crosshair_tool-0.0.96.dist-info/entry_points.txt,sha256=u5FIPVn1jqn4Kzg5K_iNnbP6L4hQw5FWjQ0UMezG2VE,96
175
- crosshair_tool-0.0.96.dist-info/top_level.txt,sha256=2jLWtM-BWg_ZYNbNfrcds0HFZD62a6J7ZIbcgcQrRk4,29
176
- crosshair_tool-0.0.96.dist-info/RECORD,,
170
+ crosshair/tools/generate_demo_table.py,sha256=Z8gPUPQM8G_szPTgagBYzvsQeWDEEhGoZCU0z5FAS3E,3827
171
+ crosshair_tool-0.0.97.dist-info/LICENSE,sha256=NVyMvNqn1pH6RSHs6RWRcJyJvORnpgGFBlF73buqYJ0,4459
172
+ crosshair_tool-0.0.97.dist-info/METADATA,sha256=JxJPOr2OMXQF5Anj5VbO1wmdPl0rLj7hbfJuueUmAMw,6508
173
+ crosshair_tool-0.0.97.dist-info/WHEEL,sha256=AtKzrIIwO6LyEQPNa-CKogjoLSeXFnST8-hqmpwwZQA,110
174
+ crosshair_tool-0.0.97.dist-info/entry_points.txt,sha256=u5FIPVn1jqn4Kzg5K_iNnbP6L4hQw5FWjQ0UMezG2VE,96
175
+ crosshair_tool-0.0.97.dist-info/top_level.txt,sha256=2jLWtM-BWg_ZYNbNfrcds0HFZD62a6J7ZIbcgcQrRk4,29
176
+ crosshair_tool-0.0.97.dist-info/RECORD,,