1 """Routine to "compile" a .py file to a .pyc (or .pyo) file.
3 This module has intimate knowledge of the format of .pyc files.
14 MAGIC
= imp
.get_magic()
16 __all__
= ["compile", "main", "PyCompileError"]
19 class PyCompileError(Exception):
20 """Exception raised when an error occurs while attempting to
23 To raise this exception, use
25 raise PyCompileError(exc_type,exc_value,file[,msg])
29 exc_type: exception type to be used in error message
30 type name can be accesses as class variable
33 exc_value: exception value to be used in error message
34 can be accesses as class variable 'exc_value'
36 file: name of file being compiled to be used in error message
37 can be accesses as class variable 'file'
39 msg: string message to be written as error message
40 If no value is given, a default exception message will be given,
41 consistent with 'standard' py_compile output.
42 message (or default) can be accesses as class variable 'msg'
46 def __init__(self
, exc_type
, exc_value
, file, msg
=''):
47 exc_type_name
= exc_type
.__name
__
48 if exc_type
is SyntaxError:
49 tbtext
= ''.join(traceback
.format_exception_only(exc_type
, exc_value
))
50 errmsg
= tbtext
.replace('File "<string>"', 'File "%s"' % file)
52 errmsg
= "Sorry: %s: %s" % (exc_type_name
,exc_value
)
54 Exception.__init
__(self
,msg
or errmsg
,exc_type_name
,exc_value
,file)
56 self
.exc_type_name
= exc_type_name
57 self
.exc_value
= exc_value
59 self
.msg
= msg
or errmsg
65 # Define an internal helper according to the platform
68 def set_creator_type(file):
69 MacOS
.SetCreatorAndType(file, 'Pyth', 'PYC ')
71 def set_creator_type(file):
75 """Internal; write a 32-bit int to a file in little-endian order."""
76 f
.write(bytes([x
& 0xff,
81 def read_encoding(file, default
):
82 """Read the first two lines of the file looking for coding: xyzzy."""
89 m
= re
.match(br
".*\bcoding:\s*(\S+)\b", line
)
91 return m
.group(1).decode("ascii")
96 def compile(file, cfile
=None, dfile
=None, doraise
=False):
97 """Byte-compile one Python source file to Python bytecode.
101 file: source filename
102 cfile: target filename; defaults to source with 'c' or 'o' appended
103 ('c' normally, 'o' in optimizing mode, giving .pyc or .pyo)
104 dfile: purported filename; defaults to source (this is the filename
105 that will show up in error messages)
106 doraise: flag indicating whether or not an exception should be
107 raised when a compile error is found. If an exception
108 occurs and this flag is set to False, a string
109 indicating the nature of the exception will be printed,
110 and the function will return to the caller. If an
111 exception occurs and this flag is set to True, a
112 PyCompileError exception will be raised.
114 Note that it isn't necessary to byte-compile Python modules for
115 execution efficiency -- Python itself byte-compiles a module when
116 it is loaded, and if it can, writes out the bytecode to the
117 corresponding .pyc (or .pyo) file.
119 However, if a Python installation is shared between users, it is a
120 good idea to byte-compile all modules upon installation, since
121 other users may not be able to write in the source directories,
122 and thus they won't be able to write the .pyc/.pyo file, and then
123 they would be byte-compiling every module each time it is loaded.
124 This can slow down program start-up considerably.
126 See compileall.py for a script/module that uses this module to
127 byte-compile all installed files (or all files in selected
131 encoding
= read_encoding(file, "utf-8")
132 f
= open(file, 'U', encoding
=encoding
)
134 timestamp
= int(os
.fstat(f
.fileno()).st_mtime
)
135 except AttributeError:
136 timestamp
= int(os
.stat(file).st_mtime
)
137 codestring
= f
.read()
139 if codestring
and codestring
[-1] != '\n':
140 codestring
= codestring
+ '\n'
142 codeobject
= builtins
.compile(codestring
, dfile
or file,'exec')
143 except Exception as err
:
144 py_exc
= PyCompileError(err
.__class
__, err
, dfile
or file)
148 sys
.stderr
.write(py_exc
.msg
+ '\n')
151 cfile
= file + (__debug__
and 'c' or 'o')
152 fc
= open(cfile
, 'wb')
153 fc
.write(b
'\0\0\0\0')
154 wr_long(fc
, timestamp
)
155 marshal
.dump(codeobject
, fc
)
160 set_creator_type(cfile
)
163 """Compile several source files.
165 The files named in 'args' (or on the command line, if 'args' is
166 not specified) are compiled and the resulting bytecode is cached
167 in the normal manner. This function does not search a directory
168 structure to locate source files; it only compiles files named
175 for filename
in args
:
177 compile(filename
, doraise
=True)
178 except PyCompileError
as err
:
179 # return value to indicate at least one failure
181 sys
.stderr
.write(err
.msg
)
184 if __name__
== "__main__":