13

How would I generate a .pyc file from a Python AST such that I could import the file from Python?

I've used compile to create a code object, then written the co_code attribute to a file, but when I try to import the file from Python, I get an ImportError: Bad magic number in output.pyc.

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
exupero
  • 9,136
  • 8
  • 47
  • 63

2 Answers2

18

The solution can be adapted from the py_compile module:

import marshal
import py_compile
import time
import ast

codeobject = compile(ast.parse('print "Hello World"'), '<string>', 'exec')

with open('output.pyc', 'wb') as fc:
    fc.write('\0\0\0\0')
    py_compile.wr_long(fc, long(time.time()))
    marshal.dump(codeobject, fc)
    fc.flush()
    fc.seek(0, 0)
    fc.write(py_compile.MAGIC)

evandrix
  • 6,041
  • 4
  • 27
  • 38
exupero
  • 9,136
  • 8
  • 47
  • 63
  • 6
    This is just what I was looking for. But I found I could just write py_compile.MAGIC first, instead of \0\0\0\0, without having to seek back to the beginning and rewrite those 4 bytes. – Matthew Dec 31 '11 at 17:06
2

The compile standard function provides this function for both Python 2.x and Python 3.x. However, you will find that the AST representation between 2.x and 3.x is quite different, so be prepared for that.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • I take it the `co_code` attribute on the returned code object is the bytecode I'm looking for? – exupero Dec 25 '11 at 02:26
  • Quite possibly. The only thing I've done with a code object is pass it to `exec` or `eval`, I haven't inspected the bytecode directly. – Greg Hewgill Dec 25 '11 at 02:29
  • I've edited the question to be more specific based on what I learned from this answer. – exupero Dec 25 '11 at 02:40
  • 2
    I believe that a "code object" is only a part of what you might find in a compiled module file. One way to create a compiled module file is to start with Python source code. I've got code that can create source code from an AST, if you're interested. – Greg Hewgill Dec 25 '11 at 02:45
  • Indeed you are correct: there appears to be a great deal of other information. – exupero Dec 25 '11 at 04:04