crosshair-tool 0.0.96__tar.gz → 0.0.97__tar.gz

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 (181) hide show
  1. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/PKG-INFO +4 -5
  2. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/__init__.py +1 -1
  3. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/_tracers.c +60 -14
  4. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/_tracers_test.py +5 -5
  5. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/codeconfig.py +3 -2
  6. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/condition_parser.py +1 -0
  7. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/core.py +6 -8
  8. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/dynamic_typing.py +3 -3
  9. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/enforce.py +1 -0
  10. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/check_examples_test.py +1 -0
  11. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/fnutil.py +2 -3
  12. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/fnutil_test.py +1 -4
  13. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/fuzz_core_test.py +9 -1
  14. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/arraylib.py +1 -1
  15. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/builtinslib.py +12 -8
  16. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/builtinslib_ch_test.py +3 -3
  17. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/builtinslib_test.py +2 -1
  18. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/datetimelib.py +1 -3
  19. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/datetimelib_ch_test.py +5 -5
  20. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/encodings/_encutil.py +11 -6
  21. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/relib.py +1 -1
  22. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/unicodedatalib_test.py +3 -3
  23. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/main.py +5 -3
  24. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/opcode_intercept.py +37 -1
  25. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/pathing_oracle.py +1 -1
  26. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/pathing_oracle_test.py +1 -1
  27. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/register_contract.py +1 -0
  28. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/register_contract_test.py +2 -4
  29. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/simplestructs.py +10 -8
  30. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/statespace.py +1 -1
  31. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/tools/generate_demo_table.py +2 -2
  32. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/tracers.py +8 -6
  33. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/util.py +6 -6
  34. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair_tool.egg-info/PKG-INFO +4 -5
  35. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair_tool.egg-info/requires.txt +3 -3
  36. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/setup.cfg +3 -1
  37. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/setup.py +4 -5
  38. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/LICENSE +0 -0
  39. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/README.md +0 -0
  40. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/__main__.py +0 -0
  41. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/_mark_stacks.h +0 -0
  42. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/_preliminaries_test.py +0 -0
  43. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/_tracers.h +0 -0
  44. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/_tracers_pycompat.h +0 -0
  45. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/abcstring.py +0 -0
  46. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/auditwall.py +0 -0
  47. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/auditwall_test.py +0 -0
  48. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/codeconfig_test.py +0 -0
  49. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/condition_parser_test.py +0 -0
  50. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/conftest.py +0 -0
  51. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/copyext.py +0 -0
  52. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/copyext_test.py +0 -0
  53. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/core_and_libs.py +0 -0
  54. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/core_regestered_types_test.py +0 -0
  55. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/core_test.py +0 -0
  56. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/diff_behavior.py +0 -0
  57. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/diff_behavior_test.py +0 -0
  58. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/dynamic_typing_test.py +0 -0
  59. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/enforce_test.py +0 -0
  60. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/__init__.py +0 -0
  61. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/bugs_detected/__init__.py +0 -0
  62. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/bugs_detected/getattr_magic.py +0 -0
  63. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/bugs_detected/hash_consistent_with_equals.py +0 -0
  64. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/bugs_detected/shopping_cart.py +0 -0
  65. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/bugs_detected/showcase.py +0 -0
  66. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/correct_code/__init__.py +0 -0
  67. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/correct_code/arith.py +0 -0
  68. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/correct_code/chess.py +0 -0
  69. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/correct_code/nesting_inference.py +0 -0
  70. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/correct_code/numpy_examples.py +0 -0
  71. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/correct_code/rolling_average.py +0 -0
  72. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/PEP316/correct_code/showcase.py +0 -0
  73. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/__init__.py +0 -0
  74. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/deal/__init__.py +0 -0
  75. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/icontract/__init__.py +0 -0
  76. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/icontract/bugs_detected/__init__.py +0 -0
  77. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/icontract/bugs_detected/showcase.py +0 -0
  78. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/icontract/bugs_detected/wrong_sign.py +0 -0
  79. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/icontract/correct_code/__init__.py +0 -0
  80. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/icontract/correct_code/arith.py +0 -0
  81. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/examples/icontract/correct_code/showcase.py +0 -0
  82. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/__init__.py +0 -0
  83. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/binascii_ch_test.py +0 -0
  84. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/binascii_test.py +0 -0
  85. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/binasciilib.py +0 -0
  86. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/bisectlib_test.py +0 -0
  87. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/codecslib.py +0 -0
  88. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/codecslib_test.py +0 -0
  89. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/collectionslib.py +0 -0
  90. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/collectionslib_ch_test.py +0 -0
  91. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/collectionslib_test.py +0 -0
  92. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/copylib.py +0 -0
  93. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/copylib_test.py +0 -0
  94. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/datetimelib_test.py +0 -0
  95. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/decimallib.py +0 -0
  96. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/decimallib_ch_test.py +0 -0
  97. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/decimallib_test.py +0 -0
  98. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/encodings/__init__.py +0 -0
  99. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/encodings/ascii.py +0 -0
  100. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/encodings/latin_1.py +0 -0
  101. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/encodings/utf_8.py +0 -0
  102. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/encodings_ch_test.py +0 -0
  103. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/fractionlib.py +0 -0
  104. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/fractionlib_test.py +0 -0
  105. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/functoolslib.py +0 -0
  106. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/functoolslib_test.py +0 -0
  107. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/hashliblib.py +0 -0
  108. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/hashliblib_test.py +0 -0
  109. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/heapqlib.py +0 -0
  110. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/heapqlib_test.py +0 -0
  111. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/importliblib.py +0 -0
  112. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/importliblib_test.py +0 -0
  113. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/iolib.py +0 -0
  114. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/iolib_ch_test.py +0 -0
  115. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/iolib_test.py +0 -0
  116. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/ipaddresslib.py +0 -0
  117. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/itertoolslib.py +0 -0
  118. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/itertoolslib_test.py +0 -0
  119. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/jsonlib.py +0 -0
  120. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/jsonlib_ch_test.py +0 -0
  121. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/jsonlib_test.py +0 -0
  122. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/mathlib.py +0 -0
  123. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/mathlib_ch_test.py +0 -0
  124. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/mathlib_test.py +0 -0
  125. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/oslib.py +0 -0
  126. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/pathliblib_test.py +0 -0
  127. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/randomlib.py +0 -0
  128. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/randomlib_test.py +0 -0
  129. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/relib_ch_test.py +0 -0
  130. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/relib_test.py +0 -0
  131. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/timelib.py +0 -0
  132. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/timelib_test.py +0 -0
  133. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/typeslib.py +0 -0
  134. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/typeslib_test.py +0 -0
  135. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/unicodedatalib.py +0 -0
  136. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/urlliblib.py +0 -0
  137. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/urlliblib_test.py +0 -0
  138. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/weakreflib.py +0 -0
  139. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/weakreflib_test.py +0 -0
  140. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/zliblib.py +0 -0
  141. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/libimpl/zliblib_test.py +0 -0
  142. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/lsp_server.py +0 -0
  143. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/lsp_server_test.py +0 -0
  144. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/main_test.py +0 -0
  145. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/objectproxy.py +0 -0
  146. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/objectproxy_test.py +0 -0
  147. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/opcode_intercept_test.py +0 -0
  148. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/options.py +0 -0
  149. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/options_test.py +0 -0
  150. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/patch_equivalence_test.py +0 -0
  151. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/path_cover.py +0 -0
  152. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/path_cover_test.py +0 -0
  153. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/path_search.py +0 -0
  154. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/path_search_test.py +0 -0
  155. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/pure_importer.py +0 -0
  156. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/pure_importer_test.py +0 -0
  157. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/py.typed +0 -0
  158. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/simplestructs_test.py +0 -0
  159. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/smtlib.py +0 -0
  160. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/smtlib_test.py +0 -0
  161. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/statespace_test.py +0 -0
  162. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/stubs_parser.py +0 -0
  163. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/stubs_parser_test.py +0 -0
  164. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/test_util.py +0 -0
  165. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/test_util_test.py +0 -0
  166. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/tools/__init__.py +0 -0
  167. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/tools/check_help_in_doc.py +0 -0
  168. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/tools/check_init_and_setup_coincide.py +0 -0
  169. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/tracers_test.py +0 -0
  170. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/type_repo.py +0 -0
  171. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/unicode_categories.py +0 -0
  172. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/unicode_categories_test.py +0 -0
  173. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/util_test.py +0 -0
  174. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/watcher.py +0 -0
  175. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/watcher_test.py +0 -0
  176. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/z3util.py +0 -0
  177. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair/z3util_test.py +0 -0
  178. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair_tool.egg-info/SOURCES.txt +0 -0
  179. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair_tool.egg-info/dependency_links.txt +0 -0
  180. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair_tool.egg-info/entry_points.txt +0 -0
  181. {crosshair_tool-0.0.96 → crosshair_tool-0.0.97}/crosshair_tool.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
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,14 +31,14 @@ 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: numpy==1.23.4; python_version < "3.12" and extra == "dev"
41
40
  Requires-Dist: numpy==1.26.0; (python_version >= "3.12" and python_version < "3.13") and extra == "dev"
42
- Requires-Dist: numpy==2.0.1; python_version >= "3.13" and extra == "dev"
41
+ Requires-Dist: numpy==2.3.3; python_version >= "3.13" and extra == "dev"
43
42
  Requires-Dist: pre-commit~=2.20; extra == "dev"
44
43
  Requires-Dist: pytest; extra == "dev"
45
44
  Requires-Dist: pytest-xdist; extra == "dev"
@@ -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"
@@ -37,6 +37,12 @@
37
37
  #include "internal/pycore_frame.h"
38
38
  #endif
39
39
 
40
+ #if PY_VERSION_HEX >= 0x030E0000
41
+ // Python 3.14+
42
+ #include "internal/pycore_interpframe_structs.h"
43
+ #include "internal/pycore_stackref.h"
44
+ #endif
45
+
40
46
 
41
47
  #if PY_VERSION_HEX >= 0x030C0000
42
48
  // Python 3.12+
@@ -60,6 +66,7 @@ const uint8_t _ch_TRACABLE_INSTRUCTIONS[256] = {
60
66
  // == 3.14
61
67
  [CALL_KW] = 1,
62
68
  [CONVERT_VALUE] = 1,
69
+ [LOAD_COMMON_CONSTANT] = 1,
63
70
  #endif
64
71
  [UNARY_NOT] = 1,
65
72
  [SET_ADD] = 1,
@@ -352,7 +359,7 @@ if (!self->trace_all_opcodes) {
352
359
  #elif PY_VERSION_HEX >= 0x030E0000
353
360
  // Python 3.14+
354
361
  if (!self->trace_all_opcodes) {
355
- PyBytesObject *code_bytes = PyCode_GetCode(pCode);
362
+ PyBytesObject *code_bytes = (PyBytesObject *)PyCode_GetCode(pCode);
356
363
  int opcode = code_bytes->ob_sval[lasti];
357
364
  int last_opcode = 255;
358
365
  uint8_t at_enabled_position = _ch_TRACABLE_INSTRUCTIONS[opcode];
@@ -932,16 +939,12 @@ TraceSwapType = {
932
939
 
933
940
  #define MODULE_DOC PyDoc_STR("CrossHair's intercepting tracer.")
934
941
 
935
-
936
-
937
- static PyObject **crosshair_tracers_stack_lookup(PyFrameObject *frame, int index) {
938
942
  #if PY_VERSION_HEX >= 0x030E0000
939
- // Python 3.14+
940
- PyCodeObject* code = _PyFrame_GetCodeBorrow(frame);
941
- _PyInterpreterFrame* interpreterFrame = frame->f_frame;
942
- return &(interpreterFrame->stackpointer[index]);
943
+ // Python 3.14+
944
+ // (does not use the crosshair_tracers_stack_lookup() helper)
943
945
  #elif PY_VERSION_HEX >= 0x030C0000
944
- // Python 3.12
946
+ // Python 3.12
947
+ static PyObject **crosshair_tracers_stack_lookup(PyFrameObject *frame, int index) {
945
948
  PyCodeObject* code = _PyFrame_GetCodeBorrow(frame);
946
949
  _PyInterpreterFrame* interpreterFrame = frame->f_frame;
947
950
  int64_t *stacks = _ch_get_stacks(code);
@@ -952,21 +955,63 @@ static PyObject **crosshair_tracers_stack_lookup(PyFrameObject *frame, int index
952
955
  }
953
956
  int stacktop = stack_contents >> 1;
954
957
  return &(interpreterFrame->localsplus[code->co_nlocalsplus + stacktop + index]);
955
- // PyObject* ret = interpreterFrame->localsplus[stacktop + index];
958
+ }
956
959
  #elif PY_VERSION_HEX >= 0x030B0000
957
- // Python 3.11
960
+ // Python 3.11
961
+ static PyObject **crosshair_tracers_stack_lookup(PyFrameObject *frame, int index) {
958
962
  _PyInterpreterFrame* interpreterFrame = frame->f_frame;
959
963
  int stacktop = interpreterFrame->stacktop;
960
964
  return &(interpreterFrame->localsplus[stacktop + index]);
965
+ }
961
966
  #elif PY_VERSION_HEX >= 0x030A0000
962
- // Python 3.10
967
+ // Python 3.10
968
+ static PyObject **crosshair_tracers_stack_lookup(PyFrameObject *frame, int index) {
963
969
  return &(frame->f_valuestack[frame->f_stackdepth + index]);
970
+ }
964
971
  #else
965
- // Python 3.8, 3.9
972
+ // Python 3.8, 3.9
973
+ static PyObject **crosshair_tracers_stack_lookup(PyFrameObject *frame, int index) {
966
974
  return &(frame->f_stacktop[index]);
975
+ }
967
976
  #endif
977
+
978
+ #if PY_VERSION_HEX >= 0x030E0000
979
+ // Python 3.14+
980
+ static PyObject *crosshair_tracers_stack_read(PyObject *self, PyObject *args)
981
+ {
982
+ PyFrameObject *frame;
983
+ int index;
984
+ if (!PyArg_ParseTuple(args, "Oi", &frame, &index)) {
985
+ return NULL;
986
+ }
987
+
988
+ _PyInterpreterFrame* interpreterFrame = frame->f_frame;
989
+ if (PyStackRef_IsNull(interpreterFrame->stackpointer[index])) {
990
+ PyErr_SetString(PyExc_ValueError, "No stack value is present");
991
+ return NULL;
992
+ } else {
993
+ return PyStackRef_AsPyObjectNew(interpreterFrame->stackpointer[index]);
994
+ }
968
995
  }
969
996
 
997
+ static PyObject* crosshair_tracers_stack_write(PyObject *self, PyObject *args)
998
+ {
999
+ PyFrameObject *frame;
1000
+ PyObject *val;
1001
+ int index;
1002
+ if (!PyArg_ParseTuple(args, "OiO", &frame, &index, &val)) {
1003
+ return NULL;
1004
+ }
1005
+ _PyInterpreterFrame* interpreterFrame = frame->f_frame;
1006
+ if (! PyStackRef_IsNull(interpreterFrame->stackpointer[index])) {
1007
+ PyStackRef_CLEAR(interpreterFrame->stackpointer[index]);
1008
+ }
1009
+ interpreterFrame->stackpointer[index] = PyStackRef_FromPyObjectNew(val);
1010
+ Py_RETURN_NONE;
1011
+ }
1012
+
1013
+ #else
1014
+
970
1015
  static PyObject *crosshair_tracers_stack_read(PyObject *self, PyObject *args)
971
1016
  {
972
1017
  PyFrameObject *frame;
@@ -988,7 +1033,6 @@ static PyObject *crosshair_tracers_stack_read(PyObject *self, PyObject *args)
988
1033
  return ret;
989
1034
  }
990
1035
  }
991
-
992
1036
  static PyObject* crosshair_tracers_stack_write(PyObject *self, PyObject *args)
993
1037
  {
994
1038
  PyFrameObject *frame;
@@ -1009,6 +1053,8 @@ static PyObject* crosshair_tracers_stack_write(PyObject *self, PyObject *args)
1009
1053
  *stackval = val;
1010
1054
  Py_RETURN_NONE;
1011
1055
  }
1056
+ #endif
1057
+
1012
1058
 
1013
1059
  static PyObject* crosshair_tracers_code_stack_depths(PyObject *self, PyObject *args)
1014
1060
  {
@@ -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):
@@ -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__":
@@ -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
@@ -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
@@ -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
@@ -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