Skip to content

Commit

Permalink
codeobj.replace
Browse files Browse the repository at this point in the history
  • Loading branch information
Zac-HD committed Jun 27, 2023
1 parent 849c6e8 commit 71f75e6
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 46 deletions.
43 changes: 0 additions & 43 deletions hypothesis-python/src/hypothesis/internal/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,49 +204,6 @@ def get_type_hints(thing):
return hints


def update_code_location(code, newfile, newlineno):
"""Take a code object and lie shamelessly about where it comes from.
Why do we want to do this? It's for really shallow reasons involving
hiding the hypothesis_temporary_module code from test runners like
pytest's verbose mode. This is a vastly disproportionate terrible
hack that I've done purely for vanity, and if you're reading this
code you're probably here because it's broken something and now
you're angry at me. Sorry.
"""
if hasattr(code, "replace"):
# Python 3.8 added positional-only params (PEP 570), and thus changed
# the layout of code objects. In beta1, the `.replace()` method was
# added to facilitate future-proof code. See BPO-37032 for details.
return code.replace(co_filename=newfile, co_firstlineno=newlineno)

else: # pragma: no cover
# This field order is accurate for 3.5 - 3.7, but not 3.8 when a new field
# was added for positional-only arguments. However it also added a .replace()
# method that we use instead of field indices, so they're fine as-is.
CODE_FIELD_ORDER = [
"co_argcount",
"co_kwonlyargcount",
"co_nlocals",
"co_stacksize",
"co_flags",
"co_code",
"co_consts",
"co_names",
"co_varnames",
"co_filename",
"co_name",
"co_firstlineno",
"co_lnotab",
"co_freevars",
"co_cellvars",
]
unpacked = [getattr(code, name) for name in CODE_FIELD_ORDER]
unpacked[CODE_FIELD_ORDER.index("co_filename")] = newfile
unpacked[CODE_FIELD_ORDER.index("co_firstlineno")] = newlineno
return type(code)(*unpacked)


# Under Python 2, math.floor and math.ceil returned floats, which cannot
# represent large integers - eg `float(2**53) == float(2**53 + 1)`.
# We therefore implement them entirely in (long) integer operations.
Expand Down
9 changes: 6 additions & 3 deletions hypothesis-python/src/hypothesis/internal/reflection.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from typing import TYPE_CHECKING, Any, Callable
from unittest.mock import _patch as PatchType

from hypothesis.internal.compat import PYPY, is_typed_named_tuple, update_code_location
from hypothesis.internal.compat import PYPY, is_typed_named_tuple
from hypothesis.utils.conventions import not_set
from hypothesis.vendor.pretty import pretty

Expand Down Expand Up @@ -608,8 +608,11 @@ def impersonate(target):
"""

def accept(f):
f.__code__ = update_code_location(
f.__code__, target.__code__.co_filename, target.__code__.co_firstlineno
# Lie shamelessly about where this code comes from, to hide the hypothesis
# internals from pytest, ipython, and other runtime introspection.
f.__code__ = f.__code__.replace(
co_filename=target.__code__.co_filename,
co_firstlineno=target.__code__.co_firstlineno,
)
f.__name__ = target.__name__
f.__module__ = target.__module__
Expand Down

0 comments on commit 71f75e6

Please sign in to comment.