Package: codetree
codetree - directly hack compiled python code objectREQUIRES PYTHON3.1QUICK TEST: $ python3.1 setup.py build dev --quicktestDESCRIPTION: codetree - directly hack compiled python code objectSUMMARY:codetree converts compiled python code objects into trees, which can be edited and recompiledRECENT CHANGELOG:20091224 - modularized package - fix install issues - added sdist check20091205 - moved source code to c++20091116 - package integratedDEMO USAGE:>>> from codetree import *>>> ## source code>>> src = 'def foo(aa):\n def closure():\n  nonlocal aa\n  aa += "!"\n  print(aa)\n return closure()\nfoo("hello")'; print( src )def foo(aa):def closure():nonlocal aaaa += "!"print(aa)return closure()foo("hello")>>> ## compile source code>>> codeobj = compile(src, '', 'exec')>>> exec( codeobj )hello!>>> ## convert code object into editable codetree>>> tree = codetree(codeobj)>>> for item in vars(tree).items(): print( item )('co_firstlineno', 1)('co_code', b'd\x00\x00\x84\x00\x00Z\x00\x00e\x00\x00d\x01\x00\x83\x01\x00\x01d\x02\x00S')('co_freevars', [])('co_name', '<module>')('co_filename', '')('co_lnotab', b'\t\x06')('co_flags', 64)('co_nlocals', 0)('co_stacksize', 2)('co_argcount', 0)('co_cellvars', [])('co_kwonlyargcount', 0)('co_varnames', [])('co_names', ['foo'])>>> ## edit / compile / exec codetree>>> element, depth, index, subtree = tree.find('hello')>>> subtree[index] = 'goodbye'>>> exec( tree.compile() )goodbye!>>> ## codetree structure>>> print( tree )codetree(co_argcount       0co_kwonlyargcount 0co_nlocals        0co_stacksize      2co_flags          64co_code           b'd\x00\x00\x84\x00\x00Z\x00\x00e\x00\x00d\x01\x00\x83\x01\x00\x01d\x02\x00S'co_constscodetree(co_argcount       1co_kwonlyargcount 0co_nlocals        2co_stacksize      2co_flags          3co_code           b'\x87\x00\x00f\x01\x00d\x01\x00\x86\x00\x00}\x01\x00|\x01\x00\x83\x00\x00S'co_constsNonecodetree(co_argcount       0co_kwonlyargcount 0co_nlocals        0co_stacksize      2co_flags          19co_code           b'\x88\x00\x00d\x01\x007\x89\x00\x00t\x00\x00\x88\x00\x00\x83\x01\x00\x01d\x00\x00S'co_constsNone!co_names          ['print']co_varnames       []co_filename       ''co_name           'closure'co_firstlineno    2co_lnotab         b'\x00\x02\n\x01'co_freevars       ['aa']co_cellvars       [])co_names          []co_varnames       ['aa', 'closure']co_filename       ''co_name           'foo'co_firstlineno    1co_lnotab         b'\x00\x01\x0f\x04'co_freevars       []co_cellvars       ['aa'])goodbyeNoneco_names          ['foo']co_varnames       []co_filename       ''co_name           '<module>'co_firstlineno    1co_lnotab         b'\t\x06'co_freevars       []co_cellvars       [])>>> ## disassemble codetree>>> print( tree.dis() )1           0 LOAD_CONST               0 (<code object foo at 0x922c848, file "", line 1>)3 MAKE_FUNCTION            06 STORE_NAME               0 (foo)7           9 LOAD_NAME                0 (foo)12 LOAD_CONST               1 ('goodbye')15 CALL_FUNCTION            118 POP_TOP19 LOAD_CONST               2 (None)22 RETURN_VALUE2           0 LOAD_CLOSURE             0 (aa)3 BUILD_TUPLE              16 LOAD_CONST               1 (<code object closure at 0x922c890, file "", line 2>)9 MAKE_CLOSURE             012 STORE_FAST               1 (closure)6          15 LOAD_FAST                1 (closure)18 CALL_FUNCTION            021 RETURN_VALUE4           0 LOAD_DEREF               0 (aa)3 LOAD_CONST               1 ('!')6 INPLACE_ADD7 STORE_DEREF              0 (aa)5          10 LOAD_GLOBAL              0 (print)13 LOAD_DEREF               0 (aa)16 CALL_FUNCTION            119 POP_TOP20 LOAD_CONST               0 (None)23 RETURN_VALUE