5

I have a compiled Python file, path/program.pyc.

I want to execute it with my current globals() and locals(). I tried:

with open('path/program.pyc','rb') as f:
   code = f.read()
   exec(code, globals(), locals())

More specifically, what I want to have is:

a.py:

a = 1
# somehow run b.pyc

b.py:

print(a)

When I run a.py, I want to see the output: 1.

Actually execfile() does exactly what I want, but it only works for .py files not .pyc files. I am looking for a version of execfile() that works for .pyc files.

Sait
  • 19,045
  • 18
  • 72
  • 99
  • 1
    You want to run the code from b in a? – Padraic Cunningham Aug 27 '15 at 23:38
  • @PadraicCunningham Yes, but I only have `b.pyc` not `b.py`. – Sait Aug 27 '15 at 23:39
  • 1
    A simple way would be to uncompyle the pyc, for small files that would involve very little overhead. https://github.com/wibiti/uncompyle2 – Padraic Cunningham Aug 27 '15 at 23:41
  • @PadraicCunningham I see. Thanks. However, isn't it upsetting you too that not being able to use the `.pyc` right away without bothering to uncompyle? Python should have been making things easier, not harder. Right? – Sait Aug 27 '15 at 23:46
  • 1
    I guess it is down to the fact that it is much easier go from source to bytecode than to bytecode to source although that is not to say that it cannot be done, I just thought of uncompyle when I saw the question, I have used it quite a few times and it worked well always. – Padraic Cunningham Aug 28 '15 at 00:06
  • If you do want to go down the uncompyle route, http://pastebin.com/209wP33v – Padraic Cunningham Aug 28 '15 at 00:25
  • @PadraicCunningham Can you post your answer as a normal answer instead of comment so that I can upvote/accept it. – Sait Aug 28 '15 at 00:27
  • sure done, you might be a better answer so no hurry in accepting – Padraic Cunningham Aug 28 '15 at 00:34
  • The variable `a` is undefined in module `b` so how would you expect that to work? –  Jun 11 '21 at 14:29

2 Answers2

3

There may be a better way but using uncompyle2 to get the source and execing will do what you need:

a = 1

import uncompyle2
from StringIO import StringIO
f = StringIO()
uncompyle2.uncompyle_file('path/program.pyc', f)
f.seek(0)
exec(f.read(), globals(), locals())

Running b.pyc from a should output 1.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
-3

Use __import__

Note that you need to use standard python package notation rather than a path and you will need to make sure your file is on sys.path

Something like __import__('path.program', globals(), locals()) should do the trick.

ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
Tim Wakeham
  • 1,029
  • 1
  • 8
  • 12