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

Reply via email to