[Python-checkins] CVS: python/dist/src/Tools/freeze freeze.py,1.37,1.38 modulefinder.py,1.15,1.16
Guido van Rossum
gvanrossum@users.sourceforge.net
Tue, 20 Mar 2001 12:43:36 -0800
Update of /cvsroot/python/python/dist/src/Tools/freeze
In directory usw-pr-cvs1:/tmp/cvs-serv32259
Modified Files:
freeze.py modulefinder.py
Log Message:
Lawrence Hudson, SF #401702: Modify co_filename in frozen programs
This patch was developed primarily to reduce the size of the
frozen binary. It is particularly useful when freezing for 'small'
platforms, such as Palm OS, where you really want to save that
last miserable byte.
A limitation of this patch is that it does not provide any feedback
about the replacements being made. As the path matching
is case-sensitive this may lead to unexpected behaviour for DOS
and Windows people, eg
> freeze.py -r C:\Python\Lib\=py\ goats.py
should probably be:
> freeze.py -r c:\python\lib\=py\ goats.py
Index: freeze.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/freeze/freeze.py,v
retrieving revision 1.37
retrieving revision 1.38
diff -C2 -r1.37 -r1.38
*** freeze.py 2000/07/16 12:04:32 1.37
--- freeze.py 2001/03/20 20:43:33 1.38
***************
*** 58,61 ****
--- 58,65 ----
is automatic.)
+ -r prefix=f: Replace path prefix.
+ Replace prefix with f in the source path references
+ contained in the resulting binary.
+
Arguments:
***************
*** 110,113 ****
--- 114,118 ----
odir = ''
win = sys.platform[:3] == 'win'
+ replace_paths = [] # settable with -r option
# default the exclude list for each platform
***************
*** 140,144 ****
# Now parse the command line with the extras inserted.
try:
! opts, args = getopt.getopt(sys.argv[1:], 'a:de:hmo:p:P:qs:wx:l:')
except getopt.error, msg:
usage('getopt error: ' + str(msg))
--- 145,149 ----
# Now parse the command line with the extras inserted.
try:
! opts, args = getopt.getopt(sys.argv[1:], 'r:a:de:hmo:p:P:qs:wx:l:')
except getopt.error, msg:
usage('getopt error: ' + str(msg))
***************
*** 175,178 ****
--- 180,186 ----
if o == '-a':
apply(modulefinder.AddPackagePath, tuple(string.split(a,"=", 2)))
+ if o == '-r':
+ f,r = string.split(a,"=", 2)
+ replace_paths.append( (f,r) )
# default prefix and exec_prefix
***************
*** 311,315 ****
dir = os.path.dirname(scriptfile)
path[0] = dir
! mf = modulefinder.ModuleFinder(path, debug, exclude)
if win and subsystem=='service':
--- 319,323 ----
dir = os.path.dirname(scriptfile)
path[0] = dir
! mf = modulefinder.ModuleFinder(path, debug, exclude, replace_paths)
if win and subsystem=='service':
Index: modulefinder.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/freeze/modulefinder.py,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -r1.15 -r1.16
*** modulefinder.py 2000/11/06 02:49:27 1.15
--- modulefinder.py 2001/03/20 20:43:34 1.16
***************
*** 8,11 ****
--- 8,12 ----
import string
import sys
+ import new
IMPORT_NAME = dis.opname.index('IMPORT_NAME')
***************
*** 50,54 ****
class ModuleFinder:
! def __init__(self, path=None, debug=0, excludes = []):
if path is None:
path = sys.path
--- 51,55 ----
class ModuleFinder:
! def __init__(self, path=None, debug=0, excludes = [], replace_paths = []):
if path is None:
path = sys.path
***************
*** 59,62 ****
--- 60,65 ----
self.indent = 0
self.excludes = excludes
+ self.replace_paths = replace_paths
+ self.processed_paths = [] # Used in debugging only
def msg(self, level, str, *args):
***************
*** 251,254 ****
--- 254,259 ----
m.__file__ = pathname
if co:
+ if self.replace_paths:
+ co = self.replace_paths_in_code(co)
m.__code__ = co
self.scan_code(co, m)
***************
*** 369,372 ****
--- 374,403 ----
mods.sort()
print "?", key, "from", string.join(mods, ', ')
+
+ def replace_paths_in_code(self, co):
+ new_filename = original_filename = os.path.normpath(co.co_filename)
+ for f,r in self.replace_paths:
+ if original_filename.startswith(f):
+ new_filename = r+original_filename[len(f):]
+ break
+
+ if self.debug and original_filename not in self.processed_paths:
+ if new_filename!=original_filename:
+ self.msgout(2, "co_filename %r changed to %r" \
+ % (original_filename,new_filename,))
+ else:
+ self.msgout(2, "co_filename %r remains unchanged" \
+ % (original_filename,))
+ self.processed_paths.append(original_filename)
+
+ consts = list(co.co_consts)
+ for i in range(len(consts)):
+ if isinstance(consts[i], type(co)):
+ consts[i] = self.replace_paths_in_code(consts[i])
+
+ return new.code(co.co_argcount, co.co_nlocals, co.co_stacksize,
+ co.co_flags, co.co_code, tuple(consts), co.co_names,
+ co.co_varnames, new_filename, co.co_name,
+ co.co_firstlineno, co.co_lnotab)