summaryrefslogtreecommitdiffstats
path: root/Tools/freeze/modulefinder.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-03-20 20:43:34 (GMT)
committerGuido van Rossum <guido@python.org>2001-03-20 20:43:34 (GMT)
commit6b767ac81aba6e51f9a84efe44d31a1db1e1edba (patch)
treec22c5455415a6f1e2b1b1757ac90aa271bd34ced /Tools/freeze/modulefinder.py
parentb845cb0946a278a1f4bf5710d471b90a18e688d5 (diff)
downloadcpython-6b767ac81aba6e51f9a84efe44d31a1db1e1edba.zip
cpython-6b767ac81aba6e51f9a84efe44d31a1db1e1edba.tar.gz
cpython-6b767ac81aba6e51f9a84efe44d31a1db1e1edba.tar.bz2
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
Diffstat (limited to 'Tools/freeze/modulefinder.py')
-rw-r--r--Tools/freeze/modulefinder.py33
1 files changed, 32 insertions, 1 deletions
diff --git a/Tools/freeze/modulefinder.py b/Tools/freeze/modulefinder.py
index 8c4b74d..42cbbab 100644
--- a/Tools/freeze/modulefinder.py
+++ b/Tools/freeze/modulefinder.py
@@ -7,6 +7,7 @@ import os
import re
import string
import sys
+import new
IMPORT_NAME = dis.opname.index('IMPORT_NAME')
IMPORT_FROM = dis.opname.index('IMPORT_FROM')
@@ -49,7 +50,7 @@ class Module:
class ModuleFinder:
- def __init__(self, path=None, debug=0, excludes = []):
+ def __init__(self, path=None, debug=0, excludes = [], replace_paths = []):
if path is None:
path = sys.path
self.path = path
@@ -58,6 +59,8 @@ class ModuleFinder:
self.debug = debug
self.indent = 0
self.excludes = excludes
+ self.replace_paths = replace_paths
+ self.processed_paths = [] # Used in debugging only
def msg(self, level, str, *args):
if level <= self.debug:
@@ -250,6 +253,8 @@ class ModuleFinder:
m = self.add_module(fqname)
m.__file__ = pathname
if co:
+ if self.replace_paths:
+ co = self.replace_paths_in_code(co)
m.__code__ = co
self.scan_code(co, m)
self.msgout(2, "load_module ->", m)
@@ -369,6 +374,32 @@ class ModuleFinder:
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)
+
def test():
# Parse command line