crosshair-tool 0.0.84__tar.gz → 0.0.85__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.
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/PKG-INFO +1 -1
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/__init__.py +1 -1
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/_mark_stacks.h +0 -25
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/_tracers.c +92 -15
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/_tracers.h +2 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/_tracers_test.py +8 -2
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/condition_parser.py +5 -5
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/condition_parser_test.py +1 -1
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/copyext.py +23 -7
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/copyext_test.py +11 -1
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/dynamic_typing.py +1 -1
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/fnutil_test.py +4 -1
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/arraylib.py +0 -13
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/builtinslib.py +22 -14
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/collectionslib.py +13 -2
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/collectionslib_test.py +10 -2
- crosshair-tool-0.0.85/crosshair/libimpl/timelib.py +72 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/timelib_test.py +12 -2
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/lsp_server.py +1 -1
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/opcode_intercept.py +23 -8
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/opcode_intercept_test.py +13 -2
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/tracers.py +27 -9
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/type_repo.py +2 -2
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/unicode_categories.py +1 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/util.py +45 -16
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair_tool.egg-info/PKG-INFO +1 -1
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/setup.cfg +1 -1
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/setup.py +1 -1
- crosshair-tool-0.0.84/crosshair/libimpl/timelib.py +0 -53
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/LICENSE +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/README.md +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/__main__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/_preliminaries_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/_tracers_pycompat.h +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/abcstring.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/auditwall.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/auditwall_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/codeconfig.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/codeconfig_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/conftest.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/core.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/core_and_libs.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/core_regestered_types_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/core_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/diff_behavior.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/diff_behavior_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/dynamic_typing_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/enforce.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/enforce_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/bugs_detected/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/bugs_detected/getattr_magic.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/bugs_detected/hash_consistent_with_equals.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/bugs_detected/shopping_cart.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/bugs_detected/showcase.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/correct_code/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/correct_code/arith.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/correct_code/chess.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/correct_code/nesting_inference.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/correct_code/numpy_examples.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/correct_code/rolling_average.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/PEP316/correct_code/showcase.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/check_examples_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/deal/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/icontract/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/icontract/bugs_detected/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/icontract/bugs_detected/showcase.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/icontract/bugs_detected/wrong_sign.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/icontract/correct_code/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/icontract/correct_code/arith.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/examples/icontract/correct_code/showcase.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/fnutil.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/fuzz_core_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/binascii_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/binascii_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/binasciilib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/bisectlib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/builtinslib_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/builtinslib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/codecslib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/codecslib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/collectionslib_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/copylib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/datetimelib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/datetimelib_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/datetimelib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/decimallib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/decimallib_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/decimallib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/encodings/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/encodings/_encutil.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/encodings/ascii.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/encodings/latin_1.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/encodings/utf_8.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/encodings_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/fractionlib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/fractionlib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/functoolslib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/functoolslib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/hashliblib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/hashliblib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/heapqlib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/heapqlib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/importliblib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/importliblib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/iolib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/iolib_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/iolib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/ipaddresslib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/itertoolslib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/itertoolslib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/jsonlib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/jsonlib_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/jsonlib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/mathlib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/mathlib_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/mathlib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/oslib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/pathliblib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/randomlib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/randomlib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/relib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/relib_ch_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/relib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/typeslib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/typeslib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/unicodedatalib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/unicodedatalib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/urlliblib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/urlliblib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/weakreflib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/weakreflib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/zliblib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/libimpl/zliblib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/lsp_server_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/main.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/main_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/objectproxy.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/objectproxy_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/options.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/options_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/patch_equivalence_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/path_cover.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/path_cover_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/path_search.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/path_search_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/pathing_oracle.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/pure_importer.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/pure_importer_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/py.typed +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/register_contract.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/register_contract_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/simplestructs.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/simplestructs_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/smtlib.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/smtlib_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/statespace.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/statespace_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/stubs_parser.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/stubs_parser_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/test_util.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/test_util_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/tools/__init__.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/tools/check_help_in_doc.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/tools/check_init_and_setup_coincide.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/tools/generate_demo_table.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/tracers_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/unicode_categories_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/util_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/watcher.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/watcher_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/z3util.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair/z3util_test.py +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair_tool.egg-info/SOURCES.txt +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair_tool.egg-info/dependency_links.txt +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair_tool.egg-info/entry_points.txt +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair_tool.egg-info/requires.txt +0 -0
- {crosshair-tool-0.0.84 → crosshair-tool-0.0.85}/crosshair_tool.egg-info/top_level.txt +0 -0
|
@@ -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.
|
|
18
|
+
__version__ = "0.0.85" # Do not forget to update in setup.py!
|
|
19
19
|
__author__ = "Phillip Schanely"
|
|
20
20
|
__license__ = "MIT"
|
|
21
21
|
__status__ = "Alpha"
|
|
@@ -538,31 +538,6 @@ static const uint8_t _ch_DE_INSTRUMENT[256] = {
|
|
|
538
538
|
#endif
|
|
539
539
|
#endif
|
|
540
540
|
|
|
541
|
-
static const uint8_t _ch_TRACABLE_INSTRUCTIONS[256] = {
|
|
542
|
-
// This must be manually kept in sync the the various
|
|
543
|
-
// instructions that we care about on the python side.
|
|
544
|
-
[MAP_ADD] = 1,
|
|
545
|
-
[BINARY_SUBSCR] = 1,
|
|
546
|
-
[BINARY_SLICE] = 1,
|
|
547
|
-
[CONTAINS_OP] = 1,
|
|
548
|
-
[BUILD_STRING] = 1,
|
|
549
|
-
#if PY_VERSION_HEX < 0x030D0000
|
|
550
|
-
// <= 3.12
|
|
551
|
-
[FORMAT_VALUE] = 1,
|
|
552
|
-
#elif PY_VERSION_HEX < 0x030E0000
|
|
553
|
-
// 3.13
|
|
554
|
-
[CALL_KW] = 1,
|
|
555
|
-
[CONVERT_VALUE] = 1,
|
|
556
|
-
#endif
|
|
557
|
-
[UNARY_NOT] = 1,
|
|
558
|
-
[SET_ADD] = 1,
|
|
559
|
-
[IS_OP] = 1,
|
|
560
|
-
[BINARY_OP] = 1,
|
|
561
|
-
[CALL] = 1,
|
|
562
|
-
[CALL_FUNCTION_EX] = 1,
|
|
563
|
-
};
|
|
564
|
-
|
|
565
|
-
|
|
566
541
|
/* Get the underlying opcode, stripping instrumentation */
|
|
567
542
|
int _ch_Py_GetBaseOpcode(PyCodeObject *code, int i)
|
|
568
543
|
{
|
|
@@ -17,20 +17,69 @@
|
|
|
17
17
|
#include <opcode.h>
|
|
18
18
|
|
|
19
19
|
#define Py_BUILD_CORE
|
|
20
|
+
#define NEED_OPCODE_METADATA
|
|
20
21
|
|
|
21
|
-
#if PY_VERSION_HEX >= 0x030C0000
|
|
22
|
-
#include "_mark_stacks.h"
|
|
23
|
-
#endif
|
|
24
22
|
|
|
25
23
|
#include "_tracers_pycompat.h"
|
|
24
|
+
#include "internal/pycore_code.h"
|
|
25
|
+
|
|
26
|
+
#if PY_VERSION_HEX >= 0x030D0000
|
|
27
|
+
// Python 3.13+
|
|
28
|
+
#include "internal/pycore_opcode_metadata.h"
|
|
29
|
+
#endif
|
|
30
|
+
|
|
26
31
|
#include "_tracers.h"
|
|
27
32
|
|
|
28
33
|
#include "frameobject.h"
|
|
29
34
|
|
|
30
35
|
#if PY_VERSION_HEX >= 0x030B0000
|
|
36
|
+
// Python 3.11+
|
|
31
37
|
#include "internal/pycore_frame.h"
|
|
32
38
|
#endif
|
|
33
39
|
|
|
40
|
+
|
|
41
|
+
#if PY_VERSION_HEX >= 0x030C0000
|
|
42
|
+
// Python 3.12+
|
|
43
|
+
const uint8_t _ch_TRACABLE_INSTRUCTIONS[256] = {
|
|
44
|
+
// This must be manually kept in sync the the various
|
|
45
|
+
// instructions that we care about on the python side.
|
|
46
|
+
[MAP_ADD] = 1,
|
|
47
|
+
[BINARY_SLICE] = 1,
|
|
48
|
+
[CONTAINS_OP] = 1,
|
|
49
|
+
[BUILD_STRING] = 1,
|
|
50
|
+
#if PY_VERSION_HEX < 0x030D0000
|
|
51
|
+
// <= 3.12
|
|
52
|
+
[FORMAT_VALUE] = 1,
|
|
53
|
+
[BINARY_SUBSCR] = 1,
|
|
54
|
+
#elif PY_VERSION_HEX < 0x030E0000
|
|
55
|
+
// == 3.13
|
|
56
|
+
[CALL_KW] = 1,
|
|
57
|
+
[CONVERT_VALUE] = 1,
|
|
58
|
+
[BINARY_SUBSCR] = 1,
|
|
59
|
+
#elif PY_VERSION_HEX < 0x030F0000
|
|
60
|
+
// == 3.14
|
|
61
|
+
[CALL_KW] = 1,
|
|
62
|
+
[CONVERT_VALUE] = 1,
|
|
63
|
+
#endif
|
|
64
|
+
[UNARY_NOT] = 1,
|
|
65
|
+
[SET_ADD] = 1,
|
|
66
|
+
[IS_OP] = 1,
|
|
67
|
+
[BINARY_OP] = 1,
|
|
68
|
+
[CALL] = 1,
|
|
69
|
+
[CALL_FUNCTION_EX] = 1,
|
|
70
|
+
};
|
|
71
|
+
#endif
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
#if PY_VERSION_HEX >= 0x030C0000
|
|
75
|
+
#if PY_VERSION_HEX < 0x030E0000
|
|
76
|
+
// Python 3.12 & 3.13
|
|
77
|
+
#define CH_STACK_COMPUTATION 1
|
|
78
|
+
#include "_mark_stacks.h"
|
|
79
|
+
#endif
|
|
80
|
+
#endif
|
|
81
|
+
|
|
82
|
+
|
|
34
83
|
static int
|
|
35
84
|
pyint_as_int(PyObject * pyint, int *pint)
|
|
36
85
|
{
|
|
@@ -92,8 +141,7 @@ CTracer_dealloc(CTracer *self)
|
|
|
92
141
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
|
93
142
|
}
|
|
94
143
|
|
|
95
|
-
#if
|
|
96
|
-
// Python 3.12
|
|
144
|
+
#if CH_STACK_COMPUTATION
|
|
97
145
|
|
|
98
146
|
#define _CODE_STACK_CACHE_CAPACITY 64
|
|
99
147
|
static CodeAndStacks _CODE_STACK_CACHE[_CODE_STACK_CACHE_CAPACITY];
|
|
@@ -183,7 +231,7 @@ CTracer_push_module(CTracer *self, PyObject *args)
|
|
|
183
231
|
continue;
|
|
184
232
|
}
|
|
185
233
|
#if PY_VERSION_HEX >= 0x030C0000
|
|
186
|
-
// Python 3.12
|
|
234
|
+
// Python 3.12+
|
|
187
235
|
if (! _ch_TRACABLE_INSTRUCTIONS[opcode]) {
|
|
188
236
|
self->trace_all_opcodes = TRUE;
|
|
189
237
|
// sys.monitoring also will need to be reset, but that happens at the python layer above
|
|
@@ -293,12 +341,36 @@ static int
|
|
|
293
341
|
CTracer_handle_opcode(CTracer *self, PyCodeObject* pCode, int lasti)
|
|
294
342
|
{
|
|
295
343
|
|
|
296
|
-
#if
|
|
297
|
-
|
|
344
|
+
#if CH_STACK_COMPUTATION
|
|
345
|
+
if (!self->trace_all_opcodes) {
|
|
346
|
+
int64_t *stacks = _ch_get_stacks(pCode);
|
|
347
|
+
uint8_t at_enabled_position = stacks[lasti / 2] & 1;
|
|
348
|
+
if (!at_enabled_position) {
|
|
349
|
+
return RET_DISABLE_TRACING;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
#elif PY_VERSION_HEX >= 0x030E0000
|
|
353
|
+
// Python 3.14+
|
|
298
354
|
if (!self->trace_all_opcodes) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
355
|
+
PyBytesObject *code_bytes = PyCode_GetCode(pCode);
|
|
356
|
+
int opcode = code_bytes->ob_sval[lasti];
|
|
357
|
+
int last_opcode = 255;
|
|
358
|
+
uint8_t at_enabled_position = _ch_TRACABLE_INSTRUCTIONS[opcode];
|
|
359
|
+
uint8_t last_instr_enabled = 0;
|
|
360
|
+
if (lasti > 1) {
|
|
361
|
+
// TODO: This seems wrong; it doesn't account for extended args or cache entries;
|
|
362
|
+
last_opcode = code_bytes->ob_sval[lasti - 2];
|
|
363
|
+
last_instr_enabled = _ch_TRACABLE_INSTRUCTIONS[last_opcode];
|
|
364
|
+
}
|
|
365
|
+
// printf("lasti: %d, func: %s, opcode: %s, last opcode (%s) enabled: %d -> %d\n", lasti,
|
|
366
|
+
// PyUnicode_AsUTF8(pCode->co_name) ? PyUnicode_AsUTF8(pCode->co_name) : "<unknown>",
|
|
367
|
+
// _PyOpcode_OpName[opcode] ? _PyOpcode_OpName[opcode] : "<unknown>",
|
|
368
|
+
// _PyOpcode_OpName[last_opcode] ? _PyOpcode_OpName[last_opcode] : "<unknown>",
|
|
369
|
+
// last_instr_enabled,
|
|
370
|
+
// at_enabled_position
|
|
371
|
+
// );
|
|
372
|
+
|
|
373
|
+
if ((!last_instr_enabled) && (!at_enabled_position)) {
|
|
302
374
|
return RET_DISABLE_TRACING;
|
|
303
375
|
}
|
|
304
376
|
}
|
|
@@ -860,7 +932,12 @@ TraceSwapType = {
|
|
|
860
932
|
|
|
861
933
|
|
|
862
934
|
static PyObject **crosshair_tracers_stack_lookup(PyFrameObject *frame, int index) {
|
|
863
|
-
#if PY_VERSION_HEX >=
|
|
935
|
+
#if PY_VERSION_HEX >= 0x030E0000
|
|
936
|
+
// Python 3.14+
|
|
937
|
+
PyCodeObject* code = _PyFrame_GetCodeBorrow(frame);
|
|
938
|
+
_PyInterpreterFrame* interpreterFrame = frame->f_frame;
|
|
939
|
+
return &(interpreterFrame->stackpointer[index]);
|
|
940
|
+
#elif PY_VERSION_HEX >= 0x030C0000
|
|
864
941
|
// Python 3.12
|
|
865
942
|
PyCodeObject* code = _PyFrame_GetCodeBorrow(frame);
|
|
866
943
|
_PyInterpreterFrame* interpreterFrame = frame->f_frame;
|
|
@@ -900,7 +977,7 @@ static PyObject *crosshair_tracers_stack_read(PyObject *self, PyObject *args)
|
|
|
900
977
|
return NULL;
|
|
901
978
|
}
|
|
902
979
|
PyObject *ret = *retaddr;
|
|
903
|
-
if (ret == NULL) {
|
|
980
|
+
if (ret == NULL || ret == 1) { // starting in 3.14, we sometimes see a sentinal 0x1 pointer (?)
|
|
904
981
|
PyErr_SetString(PyExc_ValueError, "No stack value is present");
|
|
905
982
|
return NULL;
|
|
906
983
|
} else {
|
|
@@ -937,7 +1014,7 @@ static PyObject* crosshair_tracers_code_stack_depths(PyObject *self, PyObject *a
|
|
|
937
1014
|
return NULL;
|
|
938
1015
|
}
|
|
939
1016
|
|
|
940
|
-
#if
|
|
1017
|
+
#if CH_STACK_COMPUTATION
|
|
941
1018
|
// Python 3.12
|
|
942
1019
|
int64_t *stacks = _ch_get_stacks(code);
|
|
943
1020
|
int codelen = (int)Py_SIZE(code);
|
|
@@ -961,7 +1038,7 @@ static PyObject* crosshair_tracers_supported_opcodes(PyObject *self, PyObject *a
|
|
|
961
1038
|
return NULL;
|
|
962
1039
|
}
|
|
963
1040
|
#if PY_VERSION_HEX >= 0x030C0000
|
|
964
|
-
// Python 3.12
|
|
1041
|
+
// Python 3.12+
|
|
965
1042
|
PyObject* python_val = PyList_New(0);
|
|
966
1043
|
for (int i = 0; i < 256; i++) {
|
|
967
1044
|
if (_ch_TRACABLE_INSTRUCTIONS[i]) {
|
|
@@ -89,7 +89,10 @@ def _log_execution_stacks(fn, *a, **kw):
|
|
|
89
89
|
return stacks
|
|
90
90
|
|
|
91
91
|
|
|
92
|
-
@pytest.mark.skipif(
|
|
92
|
+
@pytest.mark.skipif(
|
|
93
|
+
sys.version_info < (3, 12) or sys.version_info >= (3, 14),
|
|
94
|
+
reason="stack depths only in 3.12 & 3.13",
|
|
95
|
+
)
|
|
93
96
|
def test_one_function_stack_depth():
|
|
94
97
|
_E = (TypeError, KeyboardInterrupt)
|
|
95
98
|
|
|
@@ -100,7 +103,10 @@ def test_one_function_stack_depth():
|
|
|
100
103
|
_log_execution_stacks(a, 4)
|
|
101
104
|
|
|
102
105
|
|
|
103
|
-
@pytest.mark.skipif(
|
|
106
|
+
@pytest.mark.skipif(
|
|
107
|
+
sys.version_info < (3, 12) or sys.version_info >= (3, 14),
|
|
108
|
+
reason="stack depths only in 3.12 & 3.13",
|
|
109
|
+
)
|
|
104
110
|
def test_stack_get():
|
|
105
111
|
def to_be_traced(x):
|
|
106
112
|
r = 8 - x
|
|
@@ -47,6 +47,7 @@ from crosshair.options import AnalysisKind
|
|
|
47
47
|
from crosshair.register_contract import get_contract
|
|
48
48
|
from crosshair.tracers import NoTracing
|
|
49
49
|
from crosshair.util import (
|
|
50
|
+
CrossHairInternal,
|
|
50
51
|
DynamicScopeVar,
|
|
51
52
|
EvalFriendlyReprContext,
|
|
52
53
|
IdKeyedDict,
|
|
@@ -485,6 +486,7 @@ class ConcreteConditionParser(ConditionParser):
|
|
|
485
486
|
method = cls.__dict__.get(method_name, None)
|
|
486
487
|
super_method_conditions = super_methods.get(method_name)
|
|
487
488
|
if super_method_conditions is not None:
|
|
489
|
+
# Re-type the super's `self` argument to be this class:
|
|
488
490
|
revised_sig = set_first_arg_type(super_method_conditions.sig, cls)
|
|
489
491
|
super_method_conditions = replace(
|
|
490
492
|
super_method_conditions, sig=revised_sig
|
|
@@ -511,17 +513,15 @@ class ConcreteConditionParser(ConditionParser):
|
|
|
511
513
|
final_pre = list(conditions.pre)
|
|
512
514
|
final_post = list(conditions.post)
|
|
513
515
|
if method_name in (
|
|
514
|
-
"__new__", #
|
|
516
|
+
"__new__", # a staticmethod, but not isinstance(staticmethod)
|
|
515
517
|
"__repr__", # is itself required for reporting problems with invariants.
|
|
516
518
|
# [set/del]attr can do anything; we can't resonably enforce invariants:
|
|
517
519
|
"__setattr__",
|
|
518
520
|
"__delattr__",
|
|
521
|
+
"__replace__", # Will raise an exception with most arbitrary **kwargs.
|
|
522
|
+
"__annotate__", # a staticmethod, but not isinstance(staticmethod)
|
|
519
523
|
):
|
|
520
524
|
pass
|
|
521
|
-
elif method_name == "__replace__":
|
|
522
|
-
# TODO: remove this case when fixed in 3.13
|
|
523
|
-
# see https://github.com/python/cpython/issues/114198
|
|
524
|
-
pass
|
|
525
525
|
elif method_name == "__del__":
|
|
526
526
|
final_pre.extend(inv)
|
|
527
527
|
elif method_name == "__init__":
|
|
@@ -140,7 +140,7 @@ class TestPep316Parser:
|
|
|
140
140
|
"self.x >= 0",
|
|
141
141
|
"self.y >= 0",
|
|
142
142
|
}
|
|
143
|
-
assert set(class_conditions.methods.keys())
|
|
143
|
+
assert {"isready", "__init__"} <= set(class_conditions.methods.keys())
|
|
144
144
|
method = class_conditions.methods["isready"]
|
|
145
145
|
assert set([c.expr_source for c in method.pre]) == {
|
|
146
146
|
"self.x >= 0",
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
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
|
|
@@ -9,7 +14,7 @@ from copy import Error
|
|
|
9
14
|
from copyreg import dispatch_table # type: ignore
|
|
10
15
|
from enum import Enum
|
|
11
16
|
from types import MappingProxyType
|
|
12
|
-
from typing import Any, Dict, Tuple
|
|
17
|
+
from typing import Any, Callable, Dict, Tuple
|
|
13
18
|
|
|
14
19
|
from crosshair.tracers import ResumedTracing
|
|
15
20
|
from crosshair.util import (
|
|
@@ -85,17 +90,28 @@ def deepcopyext(obj: object, mode: CopyMode, memo: Dict) -> Any:
|
|
|
85
90
|
return cpy
|
|
86
91
|
|
|
87
92
|
|
|
93
|
+
if sys.version_info >= (3, 14):
|
|
94
|
+
|
|
95
|
+
def lookup_dispatch(cls: type) -> Callable:
|
|
96
|
+
if cls in _atomic_types:
|
|
97
|
+
return lambda obj, memo: obj
|
|
98
|
+
return _deepcopy_dispatch.get(cls)
|
|
99
|
+
|
|
100
|
+
else:
|
|
101
|
+
|
|
102
|
+
def lookup_dispatch(cls: type) -> Callable:
|
|
103
|
+
return _deepcopy_dispatch.get(cls)
|
|
104
|
+
|
|
105
|
+
|
|
88
106
|
def _deepconstruct(obj: object, mode: CopyMode, memo: Dict):
|
|
89
107
|
cls = type(obj)
|
|
90
108
|
|
|
91
109
|
def subdeepcopy(obj: object, memo: Dict):
|
|
92
110
|
return deepcopyext(obj, mode, memo)
|
|
93
111
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if creator
|
|
97
|
-
return obj
|
|
98
|
-
elif creator in (_deepcopy_dict, _deepcopy_list, _deepcopy_tuple):
|
|
112
|
+
creator = lookup_dispatch(cls)
|
|
113
|
+
if creator is not None:
|
|
114
|
+
if creator in (_deepcopy_dict, _deepcopy_list, _deepcopy_tuple):
|
|
99
115
|
return creator(obj, memo, deepcopy=subdeepcopy)
|
|
100
116
|
else:
|
|
101
117
|
# TODO: We loose subdeepcopy in this case - won't
|
|
@@ -7,7 +7,7 @@ import pytest
|
|
|
7
7
|
from crosshair.copyext import CopyMode, deepcopyext
|
|
8
8
|
from crosshair.core_and_libs import proxy_for_type, standalone_statespace
|
|
9
9
|
from crosshair.libimpl.builtinslib import SymbolicInt
|
|
10
|
-
from crosshair.tracers import NoTracing
|
|
10
|
+
from crosshair.tracers import NoTracing
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def test_deepcopyext_best_effort():
|
|
@@ -33,6 +33,16 @@ def test_deepcopyext_symbolic_set():
|
|
|
33
33
|
deepcopyext(s, CopyMode.REALIZE, {})
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def test_deepcopyext_realize_simple(space):
|
|
37
|
+
x = SymbolicInt("x")
|
|
38
|
+
input = (x,)
|
|
39
|
+
output = deepcopyext(input, CopyMode.REALIZE, {})
|
|
40
|
+
assert input is not output
|
|
41
|
+
assert input[0] is not output[0]
|
|
42
|
+
assert type(input[0]) is SymbolicInt
|
|
43
|
+
assert type(output[0]) is int
|
|
44
|
+
|
|
45
|
+
|
|
36
46
|
def test_deepcopyext_realize(space):
|
|
37
47
|
x = SymbolicInt("x")
|
|
38
48
|
lock = RLock()
|
|
@@ -4,7 +4,7 @@ from inspect import Parameter, Signature
|
|
|
4
4
|
from itertools import zip_longest
|
|
5
5
|
from typing import Any, Callable, Dict, List, Mapping, Optional, Sequence, Tuple, Type
|
|
6
6
|
|
|
7
|
-
import typing_inspect
|
|
7
|
+
import typing_inspect # type: ignore
|
|
8
8
|
|
|
9
9
|
from crosshair.util import debug # type: ignore
|
|
10
10
|
|
|
@@ -26,7 +26,10 @@ 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
|
-
|
|
29
|
+
if sys.version_info >= (3, 14):
|
|
30
|
+
assert sig == "TypeThatIsNotDefined"
|
|
31
|
+
else:
|
|
32
|
+
assert sig == "name 'TypeThatIsNotDefined' is not defined"
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
@pytest.mark.skipif(
|
|
@@ -30,19 +30,6 @@ INT_TYPE_BOUNDS: Dict[str, Tuple[int, int]] = {
|
|
|
30
30
|
INT_TYPE_SIZE = {c: array(c).itemsize for c in INT_TYPE_BOUNDS.keys()}
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
if sys.version_info >= (3, 12):
|
|
34
|
-
from collections.abc import Buffer
|
|
35
|
-
|
|
36
|
-
def is_bytes_like(obj: object) -> bool:
|
|
37
|
-
return isinstance(obj, Buffer)
|
|
38
|
-
|
|
39
|
-
else:
|
|
40
|
-
from collections.abc import ByteString
|
|
41
|
-
|
|
42
|
-
def is_bytes_like(obj: object) -> bool:
|
|
43
|
-
return isinstance(obj, (ByteString, array))
|
|
44
|
-
|
|
45
|
-
|
|
46
33
|
def pick_code(space: StateSpace) -> Tuple[str, int, int]:
|
|
47
34
|
last_idx = len(INT_TYPE_BOUNDS) - 1
|
|
48
35
|
for (idx, (code, rng)) in enumerate(INT_TYPE_BOUNDS.items()):
|
|
@@ -17,7 +17,7 @@ from dataclasses import dataclass
|
|
|
17
17
|
from itertools import zip_longest
|
|
18
18
|
from math import inf, isfinite, isinf, isnan, nan
|
|
19
19
|
from numbers import Integral, Number, Real
|
|
20
|
-
from sys import maxunicode
|
|
20
|
+
from sys import maxunicode, version_info
|
|
21
21
|
from typing import (
|
|
22
22
|
Any,
|
|
23
23
|
BinaryIO,
|
|
@@ -58,6 +58,8 @@ try:
|
|
|
58
58
|
except ImportError:
|
|
59
59
|
from z3 import FfpEQ as fpEQ
|
|
60
60
|
|
|
61
|
+
import sys
|
|
62
|
+
|
|
61
63
|
from crosshair.abcstring import AbcString
|
|
62
64
|
from crosshair.core import (
|
|
63
65
|
SymbolicFactory,
|
|
@@ -116,6 +118,7 @@ from crosshair.util import (
|
|
|
116
118
|
assert_tracing,
|
|
117
119
|
ch_stack,
|
|
118
120
|
debug,
|
|
121
|
+
is_bytes_like,
|
|
119
122
|
is_hashable,
|
|
120
123
|
is_iterable,
|
|
121
124
|
memo,
|
|
@@ -1213,10 +1216,11 @@ class SymbolicInt(SymbolicIntable, AtomicSymbolicValue):
|
|
|
1213
1216
|
cur_divisor = 10
|
|
1214
1217
|
while True:
|
|
1215
1218
|
leftover = self // cur_divisor
|
|
1216
|
-
if leftover
|
|
1219
|
+
if leftover != 0:
|
|
1220
|
+
codepoints.append(48 + (leftover % 10))
|
|
1221
|
+
cur_divisor *= 10
|
|
1222
|
+
else:
|
|
1217
1223
|
break
|
|
1218
|
-
codepoints.append(48 + (leftover % 10))
|
|
1219
|
-
cur_divisor *= 10
|
|
1220
1224
|
with NoTracing():
|
|
1221
1225
|
codepoints.reverse()
|
|
1222
1226
|
return LazyIntSymbolicStr(codepoints)
|
|
@@ -1316,7 +1320,7 @@ class SymbolicInt(SymbolicIntable, AtomicSymbolicValue):
|
|
|
1316
1320
|
z3.If(val < 128, 7, 8)))))))))
|
|
1317
1321
|
# fmt: on
|
|
1318
1322
|
|
|
1319
|
-
if
|
|
1323
|
+
if version_info >= (3, 12):
|
|
1320
1324
|
|
|
1321
1325
|
def is_integer(self):
|
|
1322
1326
|
return True
|
|
@@ -2934,7 +2938,7 @@ class AnySymbolicStr(AbcString):
|
|
|
2934
2938
|
def capitalize(self):
|
|
2935
2939
|
if self.__len__() == 0:
|
|
2936
2940
|
return ""
|
|
2937
|
-
if
|
|
2941
|
+
if version_info >= (3, 8):
|
|
2938
2942
|
firstchar = self[0].title()
|
|
2939
2943
|
else:
|
|
2940
2944
|
firstchar = self[0].upper()
|
|
@@ -3172,7 +3176,7 @@ class AnySymbolicStr(AbcString):
|
|
|
3172
3176
|
return ""
|
|
3173
3177
|
|
|
3174
3178
|
def splitlines(self, keepends=False):
|
|
3175
|
-
if
|
|
3179
|
+
if version_info < (3, 12):
|
|
3176
3180
|
if not isinstance(keepends, int):
|
|
3177
3181
|
raise TypeError
|
|
3178
3182
|
mylen = self.__len__()
|
|
@@ -3438,6 +3442,7 @@ class LazyIntSymbolicStr(AnySymbolicStr, CrossHairValue):
|
|
|
3438
3442
|
SliceView,
|
|
3439
3443
|
SequenceConcatenation,
|
|
3440
3444
|
list, # TODO: are we sharing mutable state here?
|
|
3445
|
+
tuple,
|
|
3441
3446
|
),
|
|
3442
3447
|
):
|
|
3443
3448
|
self._codepoints = smtvar
|
|
@@ -3975,7 +3980,7 @@ class BytesLike(Buffer, AbcString, CrossHairValue):
|
|
|
3975
3980
|
return False
|
|
3976
3981
|
return list(self) == list(other)
|
|
3977
3982
|
|
|
3978
|
-
if
|
|
3983
|
+
if version_info >= (3, 12):
|
|
3979
3984
|
|
|
3980
3985
|
def __buffer__(self, flags: int):
|
|
3981
3986
|
with NoTracing():
|
|
@@ -4135,7 +4140,10 @@ class SymbolicBytes(BytesLike):
|
|
|
4135
4140
|
accumulated = []
|
|
4136
4141
|
high = None
|
|
4137
4142
|
if not isinstance(hexstr, str):
|
|
4138
|
-
|
|
4143
|
+
if is_bytes_like(hexstr) and version_info >= (3, 14):
|
|
4144
|
+
hexstr = LazyIntSymbolicStr(tuple(hexstr))
|
|
4145
|
+
else:
|
|
4146
|
+
raise TypeError
|
|
4139
4147
|
for idx, ch in enumerate(hexstr):
|
|
4140
4148
|
if not ch.isascii():
|
|
4141
4149
|
raise ValueError(
|
|
@@ -4894,7 +4902,7 @@ def _int_from_bytes(
|
|
|
4894
4902
|
) -> int:
|
|
4895
4903
|
if byteorder is _MISSING:
|
|
4896
4904
|
# byteorder defaults to "big" as of 3.11
|
|
4897
|
-
if
|
|
4905
|
+
if version_info >= (3, 11):
|
|
4898
4906
|
byteorder = "big"
|
|
4899
4907
|
else:
|
|
4900
4908
|
raise TypeError
|
|
@@ -5108,7 +5116,7 @@ def make_registrations():
|
|
|
5108
5116
|
|
|
5109
5117
|
register_type(Union, make_union_choice)
|
|
5110
5118
|
|
|
5111
|
-
if
|
|
5119
|
+
if version_info >= (3, 8):
|
|
5112
5120
|
from typing import Final
|
|
5113
5121
|
|
|
5114
5122
|
register_type(Final, lambda p, t: p(t))
|
|
@@ -5266,7 +5274,7 @@ def make_registrations():
|
|
|
5266
5274
|
"upper",
|
|
5267
5275
|
"zfill",
|
|
5268
5276
|
]
|
|
5269
|
-
if
|
|
5277
|
+
if version_info >= (3, 9):
|
|
5270
5278
|
names_to_str_patch.append("removeprefix")
|
|
5271
5279
|
names_to_str_patch.append("removesuffix")
|
|
5272
5280
|
for name in names_to_str_patch:
|
|
@@ -5322,12 +5330,12 @@ def make_registrations():
|
|
|
5322
5330
|
# Patches on int
|
|
5323
5331
|
register_patch(int.__repr__, with_checked_self(int, "__repr__"))
|
|
5324
5332
|
register_patch(int.as_integer_ratio, with_checked_self(int, "as_integer_ratio"))
|
|
5325
|
-
if
|
|
5333
|
+
if version_info >= (3, 10):
|
|
5326
5334
|
register_patch(int.bit_count, with_checked_self(int, "bit_count"))
|
|
5327
5335
|
register_patch(int.bit_length, with_checked_self(int, "bit_length"))
|
|
5328
5336
|
register_patch(int.conjugate, with_checked_self(int, "conjugate"))
|
|
5329
5337
|
register_patch(int.from_bytes, _int_from_bytes)
|
|
5330
|
-
if
|
|
5338
|
+
if version_info >= (3, 12):
|
|
5331
5339
|
register_patch(int.is_integer, with_checked_self(int, "is_integer"))
|
|
5332
5340
|
register_patch(int.to_bytes, with_checked_self(int, "to_bytes"))
|
|
5333
5341
|
|
|
@@ -126,8 +126,19 @@ class ListBasedDeque(collections.abc.MutableSequence, CrossHairValue, Generic[T]
|
|
|
126
126
|
prefix.reverse()
|
|
127
127
|
self._contents = prefix + self._contents
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
if sys.version_info >= (3, 14):
|
|
130
|
+
|
|
131
|
+
def index(self, item: T, *bounds) -> int:
|
|
132
|
+
try:
|
|
133
|
+
return self._contents.index(item, *bounds)
|
|
134
|
+
except ValueError as exc:
|
|
135
|
+
exc.args = ("deque.index(x): x not in deque",)
|
|
136
|
+
raise
|
|
137
|
+
|
|
138
|
+
else:
|
|
139
|
+
|
|
140
|
+
def index(self, item: T, *bounds) -> int:
|
|
141
|
+
return self._contents.index(item, *bounds)
|
|
131
142
|
|
|
132
143
|
def insert(self, index: int, item: T) -> None:
|
|
133
144
|
self._contents.insert(index, item)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import re
|
|
1
2
|
import sys
|
|
2
3
|
from collections import Counter, defaultdict, deque, namedtuple
|
|
3
4
|
from copy import deepcopy
|
|
@@ -98,7 +99,11 @@ def test_deque_index_with_start_index_throws_correct_exception(test_list) -> Non
|
|
|
98
99
|
with pytest.raises(ValueError) as context:
|
|
99
100
|
test_list.index(1, 2)
|
|
100
101
|
|
|
101
|
-
|
|
102
|
+
if sys.version_info >= (3, 14):
|
|
103
|
+
# assert context.match(re.escape("list.index(x): x not in list"))
|
|
104
|
+
assert context.match(re.escape("deque.index(x): x not in deque"))
|
|
105
|
+
else:
|
|
106
|
+
assert context.match("1 is not in list")
|
|
102
107
|
|
|
103
108
|
|
|
104
109
|
def test_deque_index_with_start_and_end_index(test_list) -> None:
|
|
@@ -112,7 +117,10 @@ def test_deque_index_with_start_and_end_index_throws_correct_exception(
|
|
|
112
117
|
with pytest.raises(ValueError) as context:
|
|
113
118
|
test_list.index(6, 0, 1)
|
|
114
119
|
|
|
115
|
-
|
|
120
|
+
if sys.version_info >= (3, 14):
|
|
121
|
+
assert context.match(re.escape("deque.index(x): x not in deque"))
|
|
122
|
+
else:
|
|
123
|
+
assert context.match("6 is not in list")
|
|
116
124
|
|
|
117
125
|
|
|
118
126
|
def test_deque_insert(test_list) -> None:
|