karl3ļ¼ writeme.com wrote:
> This snippet appears to duplicate a code object in the online python
> interpreter i tried:
>
> import types, inspect
> f = some_function
> code_copy = types.CodeType(*[getattr(f.__code__,
> 'co_'+p.replace('string','').replace('ant','')) for p in
> inspect.signature(types.CodeType).parameters])
>
> it looks like the CodeType parameters might change across python versions or
> might not not sure
> two of them don't match the property names, 'co_code' matches with
> 'codestring' and 'co_consts' matches with 'constants'. so the two .replace
> calls perform that matching in a hacky 1-liner
to follow up here, it turns out you can call f.__code__.replace(x=y) to
construct code objects with individual properties replaced in python. it
returns a new mutated code object. i didn't yet make a sugar library to wrap
this, unsure if i will, but here's a rough handcopy of the two functions i
wrote. the current issue is that in pdb if the code is restarted the changes
have already been applied, so i thought i might add an object that tracks if
they have been.
def hotpatch_const(f, old, new):
'Mutate a constant in a foreign function.'
warnings.warn('Make sure you\'ve submitted an issue or patch to the
developers of ' + str(f) + '!')
consts = list(f.__code__.co_consts)
const_idx = consts.index(old)
try:
consts.index(old, const_idx + 1)
raise ValueError('constant multiply present')
except ValueError:
pass
consts[const_idx] = new
f.__code__ = f.__code__.replace(co_consts = tuple(consts))
return f
def hotpatch_global(f, name, new):
'Mutate a global in a foreign function.'
warnings.warn('Make sure you\'ve submitted an issue or patch to the
developers of ' + str(f) + '!')
f.__globals__[name] = new
return f