[Python-checkins] python/nondist/sandbox/setuptools/setuptools/command bdist_egg.py, 1.24, 1.25
pje@users.sourceforge.net
pje at users.sourceforge.net
Sun Jul 10 18:24:29 CEST 2005
- Previous message: [Python-checkins] python/nondist/sandbox/setuptools/setuptools dist.py, 1.13, 1.14
- Next message: [Python-checkins] python/dist/src/Tools/bgen/bgen bgenBuffer.py, 1.12, 1.13 bgenGenerator.py, 1.22, 1.23 bgenHeapBuffer.py, 1.7, 1.8 bgenObjectDefinition.py, 1.33, 1.34 bgenType.py, 1.19, 1.20 bgenVariable.py, 1.10, 1.11 scantools.py, 1.40, 1.41
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/python/python/nondist/sandbox/setuptools/setuptools/command
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1678/setuptools/command
Modified Files:
bdist_egg.py
Log Message:
First-pass implementation of zippability analysis; scans for impure
distribution or use of __file__/__path__ and selected 'inspect' operations.
Currently, the analysis is a bit overconservative; when the runtime is more
robust, it should probably allow extensions to be zipped by default.
Index: bdist_egg.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/setuptools/setuptools/command/bdist_egg.py,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- bdist_egg.py 10 Jul 2005 05:06:31 -0000 1.24
+++ bdist_egg.py 10 Jul 2005 16:24:26 -0000 1.25
@@ -3,13 +3,13 @@
Build .egg distributions"""
# This module should be kept compatible with Python 2.3
-import os
+import os, marshal
from setuptools import Command
from distutils.dir_util import remove_tree, mkpath
from distutils.sysconfig import get_python_version, get_python_lib
from distutils import log
from pkg_resources import get_platform, Distribution
-
+from types import CodeType
def write_stub(resource, pyfile):
f = open(pyfile,'w')
@@ -175,11 +175,12 @@
ext_outputs = cmd._mutate_outputs(
self.distribution.has_ext_modules(), 'build_ext', 'build_lib', ''
)
-
+ self.stubs = []
to_compile = []
for (p,ext_name) in enumerate(ext_outputs):
filename,ext = os.path.splitext(ext_name)
pyfile = os.path.join(self.bdist_dir, filename + '.py')
+ self.stubs.append(pyfile)
log.info("creating stub loader for %s" % ext_name)
if not self.dry_run:
write_stub(os.path.basename(ext_name), pyfile)
@@ -202,7 +203,6 @@
log.info("installing scripts to %s" % script_dir)
self.call_command('install_scripts', install_dir=script_dir)
-
native_libs = os.path.join(self.egg_info,"native_libs.txt")
if ext_outputs:
log.info("writing %s" % native_libs)
@@ -221,6 +221,10 @@
if os.path.isfile(path):
self.copy_file(path,os.path.join(egg_info,filename))
+ # Write a zip safety flag file
+ flag = self.zip_safe() and 'zip-safe' or 'not-zip-safe'
+ open(os.path.join(archive_root,'EGG-INFO',flag),'w').close()
+
if os.path.exists(os.path.join(self.egg_info,'depends.txt')):
log.warn(
"WARNING: 'depends.txt' will not be used by setuptools 0.6!\n"
@@ -240,49 +244,86 @@
('bdist_egg',get_python_version(),self.egg_output))
-
-
-
-
def zap_pyfiles(self):
log.info("Removing .py files from temporary directory")
- for base,dirs,files in os.walk(self.bdist_dir):
- if 'EGG-INFO' in dirs:
- dirs.remove('EGG-INFO')
+ for base,dirs,files in self.walk_contents():
for name in files:
if name.endswith('.py'):
path = os.path.join(base,name)
log.debug("Deleting %s", path)
os.unlink(path)
+ def walk_contents(self):
+ """Walk files about to be archived, skipping the metadata directory"""
+ walker = os.walk(self.bdist_dir)
+ base,dirs,files = walker.next()
+ if 'EGG-INFO' in dirs:
+ dirs.remove('EGG-INFO')
+ yield base,dirs,files
+ for bdf in walker:
+ yield bdf
+
+ def zip_safe(self):
+ safe = getattr(self.distribution,'zip_safe',None)
+ if safe is not None:
+ return safe
+ log.warn("zip_safe flag not set; analyzing archive contents...")
+ safe = True
+ for base, dirs, files in self.walk_contents():
+ for name in files:
+ if name.endswith('.py') or name.endswith('.pyw'):
+ continue
+ elif name.endswith('.pyc') or name.endswith('.pyo'):
+ # always scan, even if we already know we're not safe
+ safe = self.scan_module(base, name) and safe
+ elif safe:
+ log.warn(
+ "Distribution contains data or extensions; assuming "
+ "it's unsafe (set zip_safe=True in setup() to change"
+ )
+ safe = False # XXX
+ return safe
+ def scan_module(self, base, name):
+ """Check whether module possibly uses unsafe-for-zipfile stuff"""
+ filename = os.path.join(base,name)
+ if filename[:-1] in self.stubs:
+ return True # Extension module
+ pkg = base[len(self.bdist_dir)+1:].replace(os.sep,'.')
+ module = pkg+(pkg and '.' or '')+os.path.splitext(name)[0]
+ f = open(filename,'rb'); f.read(8) # skip magic & date
+ code = marshal.load(f); f.close()
+ safe = True
+ symbols = dict.fromkeys(iter_symbols(code))
+ for bad in ['__file__', '__path__']:
+ if bad in symbols:
+ log.warn("%s: module references %s", module, bad)
+ safe = False
+ if 'inspect' in symbols:
+ for bad in [
+ 'getsource', 'getabsfile', 'getsourcefile', 'getfile'
+ 'getsourcelines', 'findsource', 'getcomments', 'getframeinfo',
+ 'getinnerframes', 'getouterframes', 'stack', 'trace'
+ ]:
+ if bad in symbols:
+ log.warn("%s: module MAY be using inspect.%s", module, bad)
+ safe = False
+ return safe
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+def iter_symbols(code):
+ """Yield names and strings used by `code` and its nested code objects"""
+ for name in code.co_names: yield name
+ for const in code.co_consts:
+ if isinstance(const,basestring):
+ yield const
+ elif isinstance(const,CodeType):
+ for name in iter_symbols(const):
+ yield name
# Attribute names of options for commands that might need to be convinced to
- Previous message: [Python-checkins] python/nondist/sandbox/setuptools/setuptools dist.py, 1.13, 1.14
- Next message: [Python-checkins] python/dist/src/Tools/bgen/bgen bgenBuffer.py, 1.12, 1.13 bgenGenerator.py, 1.22, 1.23 bgenHeapBuffer.py, 1.7, 1.8 bgenObjectDefinition.py, 1.33, 1.34 bgenType.py, 1.19, 1.20 bgenVariable.py, 1.10, 1.11 scantools.py, 1.40, 1.41
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Python-checkins
mailing list