1.1 Overview

The objects implemented in this package, most notably in the code_editor module, are modelled closely after those found in the Python interpreter. So, for example, a Function object has func_doc, func_name, func_code, func_defaults and func_globals attributes, just like a core Python function. What's different is that all these attributes are editable, and func_code is an instance of the EditableCode class.

Objects have references back up this heirachy, so if "func" is a Function object, then "func.func_code.co_code.code.function" is the same function. Experienced Pythonists will realize that this arrangement is likely to lead to cyclic references and so to memory leaks. However bytecodehacks uses some acquisition style skullduggery to avoid these. Said skullduggery does unpleasant things to performance, so I'm looking for ways to improve this area.

A consequence of this you should be aware of is that "func.func_code.co_code.code.function" above is not actually the same object as "func", so don't use is on objects from bytecodehacks. All relavent objects define __cmp__ methods that perform logical is-style matching. Another consequence is that you shouldn't poke around in the internals of the classes without due care and attention unless you want your head to explode and your memory to leak.

Strings of bytecode (and that's what this package is fundamentally about) are represented as CodeStrings which behave like lists of opcode objects. The bytecodehacks.ops module contains a class for each bytecode known to the Python interpreter (at least for version 1.5.2).

Enough talk, let's have a extended, silly, example.

def f():
    return 1

from bytecodehacks.code_editor import Function

ff=Function(f)

print ff.func_code.co_consts 
         => [None, 1]

ff.func_code.co_consts[1] = "cabbage"

fff=ff.make_function()

print fff(), f()
         => cabbage 1

print ff.func_code.co_code[:]
         => [LOAD_CONST 1, RETURN_VALUE]

from bytecodehacks.ops import *

ff.func_code.co_code[0] = LOAD_GLOBAL("h")

fff=ff.make_function()

h = 2

print fff()
         => 2

You get the idea, I hope. It should be obvious that the package isn't really designed for interactive use like this, more as a library for writing routines that actually do something useful.

Send comments to mwh@python.net