3

The following code produces bytecode output as string. I want to replace some lines of the bytecode and reassemble and exec it. Do I need something like the ByteCodeAssember or can I do this with PyCode New?

http://docs.python.org/2/c-api/code.html#PyCode_New

http://pypi.python.org/pypi/BytecodeAssembler

output

********** code ********** 
type: <type 'str'> 
def test(a,b): 
 return a*b 
test(2,3) 
********** compiles into the bytecode ********** 
type: <type 'code'> 
 1 0 LOAD_CONST 0 (<code object test at 0x101d1ca30, file "<string>", line 1>) 
 3 MAKE_FUNCTION 0 
 6 STORE_NAME 0 (test) 
 3 9 LOAD_NAME 0 (test) 
 12 LOAD_CONST 1 (2) 
 15 LOAD_CONST 2 (3) 
 18 CALL_FUNCTION 2 
 21 POP_TOP 
 22 LOAD_CONST 3 (None) 
 25 RETURN_VALUE 3 
********** bytecode **********
'd\x00\x00\x84\x00\x00Z\x00\x00e\x00\x00d\x01\x00d\x02\x00\x83\x02\x00\x01d\x03\x00S'

code

import dis 
import sys 
import inspect 
import new 
class writer: 
 def __init__(self): 
 self.s = "" 
 def write(self,text): 
 #print ': ',text 
 self.s += text 
#save stdout 
origstdout = sys.stdout 
w = writer() 
sys.stdout = w 
s = "def test(a,b):\n\treturn a*b\ntest(2,3)" 
c = compile(s,'<string>','exec') 
# dis calls stdout, so output is in w 
bytecode = dis.dis(c) 
sys.stdout = origstdout 
def h(x): 
 print '*'*10 + '\t' + x + '\t' + '*'*10 + '\n'*1 
h('code') 
print 'type: '+str(type(s)) 
print s + '\n' 
h('compiles into the bytecode') 
print 'type: '+str(type(c)) 
print w.s
h('bytecode') 
print repr(c.co_code) 
asked Nov 6, 2012 at 13:16
1
  • I've seen other answers, like this one where people have modified bytecode without using PyCode at all which might help you. Note esp the add_self() function. Commented Nov 6, 2012 at 13:53

1 Answer 1

2

Byteplay is a nice wrapper for python code objects. It has its own code class. Code objects is CPython specific and more complicated. To get started certainly better to play with byteplay first.

from byteplay import * 
def foo(): 
 x = 10 
 print 'inside ',x 
 return 42 
c = Code.from_code(foo.func_code) 
print c.code 
ret = foo() 
print 'outside: ',ret 
c.code[10] = (LOAD_CONST,1000) 
foo.func_code = c.to_code() 
print '*'*20 
print c.code 
ret = foo() 
print 'outside: ',ret 

produces

 4 1 LOAD_CONST 10
 2 STORE_FAST x
 5 4 LOAD_CONST 'inside '
 5 PRINT_ITEM 
 6 LOAD_FAST x
 7 PRINT_ITEM 
 8 PRINT_NEWLINE 
 6 10 LOAD_CONST 42
 11 RETURN_VALUE 
inside 10
outside: 42
********************
 4 1 LOAD_CONST 10
 2 STORE_FAST x
 5 4 LOAD_CONST 'inside '
 5 PRINT_ITEM 
 6 LOAD_FAST x
 7 PRINT_ITEM 
 8 PRINT_NEWLINE 
 6 10 LOAD_CONST 1000
 11 RETURN_VALUE 
inside 10
outside: 1000
answered Nov 6, 2012 at 16:19
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.