mirror of
https://github.com/python/cpython.git
synced 2025-11-14 07:49:28 +00:00
GH-129386: Add test.support.reset_code (GH-129486)
This commit is contained in:
parent
e3eba8ce26
commit
674befbd7b
6 changed files with 22 additions and 9 deletions
|
|
@ -66,6 +66,7 @@ __all__ = [
|
||||||
"BrokenIter",
|
"BrokenIter",
|
||||||
"in_systemd_nspawn_sync_suppressed",
|
"in_systemd_nspawn_sync_suppressed",
|
||||||
"run_no_yield_async_fn", "run_yielding_async_fn", "async_yield",
|
"run_no_yield_async_fn", "run_yielding_async_fn", "async_yield",
|
||||||
|
"reset_code",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1286,6 +1287,12 @@ def requires_specialization_ft(test):
|
||||||
_opcode.ENABLE_SPECIALIZATION_FT, "requires specialization")(test)
|
_opcode.ENABLE_SPECIALIZATION_FT, "requires specialization")(test)
|
||||||
|
|
||||||
|
|
||||||
|
def reset_code(f: types.FunctionType) -> types.FunctionType:
|
||||||
|
"""Clear all specializations, local instrumentation, and JIT code for the given function."""
|
||||||
|
f.__code__ = f.__code__.replace()
|
||||||
|
return f
|
||||||
|
|
||||||
|
|
||||||
#=======================================================================
|
#=======================================================================
|
||||||
# Check for the presence of docstrings.
|
# Check for the presence of docstrings.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ import os
|
||||||
import _opcode
|
import _opcode
|
||||||
|
|
||||||
from test.support import (script_helper, requires_specialization,
|
from test.support import (script_helper, requires_specialization,
|
||||||
import_helper, Py_GIL_DISABLED, requires_jit_enabled)
|
import_helper, Py_GIL_DISABLED, requires_jit_enabled,
|
||||||
|
reset_code)
|
||||||
|
|
||||||
_testinternalcapi = import_helper.import_module("_testinternalcapi")
|
_testinternalcapi = import_helper.import_module("_testinternalcapi")
|
||||||
|
|
||||||
|
|
@ -19,11 +20,11 @@ from _testinternalcapi import TIER2_THRESHOLD
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def clear_executors(func):
|
def clear_executors(func):
|
||||||
# Clear executors in func before and after running a block
|
# Clear executors in func before and after running a block
|
||||||
func.__code__ = func.__code__.replace()
|
reset_code(func)
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
func.__code__ = func.__code__.replace()
|
reset_code(func)
|
||||||
|
|
||||||
|
|
||||||
def get_first_executor(func):
|
def get_first_executor(func):
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import types
|
||||||
import unittest
|
import unittest
|
||||||
from test.support import (captured_stdout, requires_debug_ranges,
|
from test.support import (captured_stdout, requires_debug_ranges,
|
||||||
requires_specialization, cpython_only,
|
requires_specialization, cpython_only,
|
||||||
os_helper, import_helper)
|
os_helper, import_helper, reset_code)
|
||||||
from test.support.bytecode_helper import BytecodeTestCase
|
from test.support.bytecode_helper import BytecodeTestCase
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1356,7 +1356,7 @@ class DisTests(DisTestBase):
|
||||||
self.code_quicken(f)
|
self.code_quicken(f)
|
||||||
else:
|
else:
|
||||||
# "copy" the code to un-quicken it:
|
# "copy" the code to un-quicken it:
|
||||||
f.__code__ = f.__code__.replace()
|
reset_code(f)
|
||||||
for instruction in _unroll_caches_as_Instructions(dis.get_instructions(
|
for instruction in _unroll_caches_as_Instructions(dis.get_instructions(
|
||||||
f, show_caches=True, adaptive=adaptive
|
f, show_caches=True, adaptive=adaptive
|
||||||
), show_caches=True):
|
), show_caches=True):
|
||||||
|
|
|
||||||
|
|
@ -391,6 +391,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
import importlib._bootstrap
|
import importlib._bootstrap
|
||||||
import opcode
|
import opcode
|
||||||
import test.test_dis
|
import test.test_dis
|
||||||
|
import test.support
|
||||||
|
|
||||||
def is_specialized(f):
|
def is_specialized(f):
|
||||||
for instruction in dis.get_instructions(f, adaptive=True):
|
for instruction in dis.get_instructions(f, adaptive=True):
|
||||||
|
|
@ -409,7 +410,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
func = importlib._bootstrap._handle_fromlist
|
func = importlib._bootstrap._handle_fromlist
|
||||||
|
|
||||||
# "copy" the code to un-specialize it:
|
# "copy" the code to un-specialize it:
|
||||||
func.__code__ = func.__code__.replace()
|
test.support.reset_code(func)
|
||||||
|
|
||||||
assert not is_specialized(func), "specialized instructions found"
|
assert not is_specialized(func), "specialized instructions found"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import types
|
||||||
import unittest
|
import unittest
|
||||||
from test.support import (threading_helper, check_impl_detail,
|
from test.support import (threading_helper, check_impl_detail,
|
||||||
requires_specialization, requires_specialization_ft,
|
requires_specialization, requires_specialization_ft,
|
||||||
cpython_only, requires_jit_disabled)
|
cpython_only, requires_jit_disabled, reset_code)
|
||||||
from test.support.import_helper import import_module
|
from test.support.import_helper import import_module
|
||||||
|
|
||||||
# Skip this module on other interpreters, it is cpython specific:
|
# Skip this module on other interpreters, it is cpython specific:
|
||||||
|
|
@ -579,9 +579,9 @@ class TestRacesDoNotCrash(TestBase):
|
||||||
# Reset:
|
# Reset:
|
||||||
if check_items:
|
if check_items:
|
||||||
for item in items:
|
for item in items:
|
||||||
item.__code__ = item.__code__.replace()
|
reset_code(item)
|
||||||
else:
|
else:
|
||||||
read.__code__ = read.__code__.replace()
|
reset_code(read)
|
||||||
# Specialize:
|
# Specialize:
|
||||||
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
|
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
|
||||||
read(items)
|
read(items)
|
||||||
|
|
@ -1552,6 +1552,7 @@ class TestSpecializer(TestBase):
|
||||||
class C:
|
class C:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@reset_code
|
||||||
def set_value(n):
|
def set_value(n):
|
||||||
c = C()
|
c = C()
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
|
|
@ -1577,6 +1578,7 @@ class TestSpecializer(TestBase):
|
||||||
for i in range(_testinternalcapi.SHARED_KEYS_MAX_SIZE - 1):
|
for i in range(_testinternalcapi.SHARED_KEYS_MAX_SIZE - 1):
|
||||||
setattr(c, f"_{i}", None)
|
setattr(c, f"_{i}", None)
|
||||||
|
|
||||||
|
@reset_code
|
||||||
def set_value(n):
|
def set_value(n):
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
c.x = i
|
c.x = i
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Add ``test.support.reset_code``, which can be used to reset various
|
||||||
|
bytecode-level optimizations and local instrumentation for a function.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue