blob: 4a3a8a0528f8e8b35e1ce91fe464f43f2bdf8939 [file] [log] [blame]
Guido van Rossum63566e21998-01-19 04:01:26 +00001"""Routine to "compile" a .py file to a .pyc (or .pyo) file.
2
3This module has intimate knowledge of the format of .pyc files.
4"""
Guido van Rossum3bb54481994-08-29 10:52:58 +00005
Fred Drakea96f1a32002-08-21 20:23:22 +00006import __builtin__
Sjoerd Mullender2e5168c1995-07-19 11:21:47 +00007import imp
Fred Drakea96f1a32002-08-21 20:23:22 +00008import marshal
9import os
10import sys
11import traceback
12
Sjoerd Mullender2e5168c1995-07-19 11:21:47 +000013MAGIC = imp.get_magic()
Guido van Rossum3bb54481994-08-29 10:52:58 +000014
Skip Montanaroc62c81e2001-02-12 02:00:42 +000015__all__ = ["compile"]
16
Fred Drakea96f1a32002-08-21 20:23:22 +000017# Define an internal helper according to the platform
18if os.name == "mac":
19 import macfs
20 def set_creator_type(file):
21 macfs.FSSpec(file).SetCreatorType('Pyth', 'PYC ')
22else:
23 def set_creator_type(file):
24 pass
25
Guido van Rossum3bb54481994-08-29 10:52:58 +000026def wr_long(f, x):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000027 """Internal; write a 32-bit int to a file in little-endian order."""
Guido van Rossum63566e21998-01-19 04:01:26 +000028 f.write(chr( x & 0xff))
29 f.write(chr((x >> 8) & 0xff))
30 f.write(chr((x >> 16) & 0xff))
31 f.write(chr((x >> 24) & 0xff))
Guido van Rossum3bb54481994-08-29 10:52:58 +000032
Guido van Rossum63566e21998-01-19 04:01:26 +000033def compile(file, cfile=None, dfile=None):
34 """Byte-compile one Python source file to Python bytecode.
35
36 Arguments:
37
38 file: source filename
39 cfile: target filename; defaults to source with 'c' or 'o' appended
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000040 ('c' normally, 'o' in optimizing mode, giving .pyc or .pyo)
Guido van Rossum63566e21998-01-19 04:01:26 +000041 dfile: purported filename; defaults to source (this is the filename
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000042 that will show up in error messages)
Guido van Rossum63566e21998-01-19 04:01:26 +000043
44 Note that it isn't necessary to byte-compile Python modules for
45 execution efficiency -- Python itself byte-compiles a module when
46 it is loaded, and if it can, writes out the bytecode to the
47 corresponding .pyc (or .pyo) file.
48
49 However, if a Python installation is shared between users, it is a
50 good idea to byte-compile all modules upon installation, since
51 other users may not be able to write in the source directories,
52 and thus they won't be able to write the .pyc/.pyo file, and then
53 they would be byte-compiling every module each time it is loaded.
54 This can slow down program start-up considerably.
55
56 See compileall.py for a script/module that uses this module to
57 byte-compile all installed files (or all files in selected
58 directories).
59
60 """
Jack Jansen7b8c7542002-04-14 20:12:41 +000061 f = open(file, 'U')
Guido van Rossum63566e21998-01-19 04:01:26 +000062 try:
Raymond Hettinger32200ae2002-06-01 19:51:15 +000063 timestamp = long(os.fstat(f.fileno()).st_mtime)
Guido van Rossum63566e21998-01-19 04:01:26 +000064 except AttributeError:
Raymond Hettinger32200ae2002-06-01 19:51:15 +000065 timestamp = long(os.stat(file).st_mtime)
Guido van Rossum63566e21998-01-19 04:01:26 +000066 codestring = f.read()
67 f.close()
68 if codestring and codestring[-1] != '\n':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000069 codestring = codestring + '\n'
Guido van Rossumf984a651998-09-29 15:57:42 +000070 try:
71 codeobject = __builtin__.compile(codestring, dfile or file, 'exec')
72 except SyntaxError, detail:
Guido van Rossumf984a651998-09-29 15:57:42 +000073 lines = traceback.format_exception_only(SyntaxError, detail)
74 for line in lines:
Eric S. Raymond6b71e742001-02-09 08:56:30 +000075 sys.stderr.write(line.replace('File "<string>"',
Fred Drakea96f1a32002-08-21 20:23:22 +000076 'File "%s"' % (dfile or file)))
Guido van Rossumf984a651998-09-29 15:57:42 +000077 return
Raymond Hettinger16e3c422002-06-01 16:07:16 +000078 if cfile is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000079 cfile = file + (__debug__ and 'c' or 'o')
Guido van Rossum63566e21998-01-19 04:01:26 +000080 fc = open(cfile, 'wb')
81 fc.write('\0\0\0\0')
82 wr_long(fc, timestamp)
83 marshal.dump(codeobject, fc)
84 fc.flush()
85 fc.seek(0, 0)
86 fc.write(MAGIC)
87 fc.close()
Fred Drakea96f1a32002-08-21 20:23:22 +000088 set_creator_type(cfile)