Whitespace normalization, via reindent.py.

This commit is contained in:
Tim Peters 2004-07-18 06:16:08 +00:00
parent e6ddc8b20b
commit 182b5aca27
453 changed files with 31318 additions and 31452 deletions

View file

@ -1,6 +1,6 @@
"""Package Install Manager for Python.
This is currently a MacOSX-only strawman implementation.
This is currently a MacOSX-only strawman implementation.
Despite other rumours the name stands for "Packman IMPlementation".
Tools to allow easy installation of packages. The idea is that there is
@ -27,7 +27,7 @@ import tempfile
import shutil
import time
__all__ = ["PimpPreferences", "PimpDatabase", "PimpPackage", "main",
__all__ = ["PimpPreferences", "PimpDatabase", "PimpPackage", "main",
"PIMP_VERSION", "main"]
_scriptExc_NotInstalled = "pimp._scriptExc_NotInstalled"
@ -52,12 +52,12 @@ def getDefaultDatabase(experimental=False):
status = "exp"
else:
status = "prod"
major, minor, micro, state, extra = sys.version_info
pyvers = '%d.%d' % (major, minor)
if state != 'final':
pyvers = pyvers + '%s%d' % (state, extra)
longplatform = distutils.util.get_platform()
osname, release, machine = longplatform.split('-')
# For some platforms we may want to differentiate between
@ -94,7 +94,7 @@ def getDefaultDatabase(experimental=False):
def _cmd(output, dir, *cmditems):
"""Internal routine to run a shell command in a given directory."""
cmd = ("cd \"%s\"; " % dir) + " ".join(cmditems)
if output:
output.write("+ %s\n" % cmd)
@ -112,22 +112,22 @@ def _cmd(output, dir, *cmditems):
class PimpDownloader:
"""Abstract base class - Downloader for archives"""
def __init__(self, argument,
dir="",
watcher=None):
self.argument = argument
self._dir = dir
self._watcher = watcher
def download(self, url, filename, output=None):
return None
def update(self, str):
if self._watcher:
return self._watcher.update(str)
return True
class PimpCurlDownloader(PimpDownloader):
def download(self, url, filename, output=None):
@ -138,7 +138,7 @@ class PimpCurlDownloader(PimpDownloader):
url)
self.update("Downloading %s: finished" % url)
return (not exitstatus)
class PimpUrllibDownloader(PimpDownloader):
def download(self, url, filename, output=None):
@ -150,13 +150,13 @@ class PimpUrllibDownloader(PimpDownloader):
length = long(download.headers['content-length'])
else:
length = -1
data = download.read(4096) #read 4K at a time
dlsize = 0
lasttime = 0
while keepgoing:
dlsize = dlsize + len(data)
if len(data) == 0:
if len(data) == 0:
#this is our exit condition
break
output.write(data)
@ -171,12 +171,12 @@ class PimpUrllibDownloader(PimpDownloader):
if keepgoing:
self.update("Downloading %s: finished" % url)
return keepgoing
class PimpUnpacker:
"""Abstract base class - Unpacker for archives"""
_can_rename = False
def __init__(self, argument,
dir="",
renames=[],
@ -187,30 +187,30 @@ class PimpUnpacker:
self._dir = dir
self._renames = renames
self._watcher = watcher
def unpack(self, archive, output=None, package=None):
return None
def update(self, str):
if self._watcher:
return self._watcher.update(str)
return True
class PimpCommandUnpacker(PimpUnpacker):
"""Unpack archives by calling a Unix utility"""
_can_rename = False
def unpack(self, archive, output=None, package=None):
cmd = self.argument % archive
if _cmd(output, self._dir, cmd):
return "unpack command failed"
class PimpTarUnpacker(PimpUnpacker):
"""Unpack tarfiles using the builtin tarfile module"""
_can_rename = True
def unpack(self, archive, output=None, package=None):
tf = tarfile.open(archive, "r")
members = tf.getmembers()
@ -253,7 +253,7 @@ class PimpTarUnpacker(PimpUnpacker):
names = package.filterExpectedSkips(names)
if names:
return "Not all files were unpacked: %s" % " ".join(names)
ARCHIVE_FORMATS = [
(".tar.Z", PimpTarUnpacker, None),
(".taz", PimpTarUnpacker, None),
@ -266,8 +266,8 @@ ARCHIVE_FORMATS = [
class PimpPreferences:
"""Container for per-user preferences, such as the database to use
and where to install packages."""
def __init__(self,
def __init__(self,
flavorOrder=None,
downloadDir=None,
buildDir=None,
@ -287,10 +287,10 @@ class PimpPreferences:
self.buildDir = buildDir
self.pimpDatabase = pimpDatabase
self.watcher = None
def setWatcher(self, watcher):
self.watcher = watcher
def setInstallDir(self, installDir=None):
if installDir:
# Installing to non-standard location.
@ -303,14 +303,14 @@ class PimpPreferences:
installDir = DEFAULT_INSTALLDIR
self.installLocations = []
self.installDir = installDir
def isUserInstall(self):
return self.installDir != DEFAULT_INSTALLDIR
def check(self):
"""Check that the preferences make sense: directories exist and are
writable, the install directory is on sys.path, etc."""
rv = ""
RWX_OK = os.R_OK|os.W_OK|os.X_OK
if not os.path.exists(self.downloadDir):
@ -337,7 +337,7 @@ class PimpPreferences:
else:
rv += "Warning: Install directory \"%s\" is not on sys.path\n" % self.installDir
return rv
def compareFlavors(self, left, right):
"""Compare two flavor strings. This is part of your preferences
because whether the user prefers installing from source or binary is."""
@ -348,13 +348,13 @@ class PimpPreferences:
if right in self.flavorOrder:
return 1
return cmp(left, right)
class PimpDatabase:
"""Class representing a pimp database. It can actually contain
information from multiple databases through inclusion, but the
toplevel database is considered the master, as its maintainer is
"responsible" for the contents."""
def __init__(self, prefs):
self._packages = []
self.preferences = prefs
@ -363,23 +363,23 @@ class PimpDatabase:
self._version = ""
self._maintainer = ""
self._description = ""
# Accessor functions
def url(self): return self._url
def version(self): return self._version
def maintainer(self): return self._maintainer
def description(self): return self._description
def close(self):
"""Clean up"""
self._packages = []
self.preferences = None
def appendURL(self, url, included=0):
"""Append packages from the database with the given URL.
Only the first database should specify included=0, so the
global information (maintainer, description) get stored."""
if url in self._urllist:
return
self._urllist.append(url)
@ -396,7 +396,7 @@ class PimpDatabase:
if not self._version:
sys.stderr.write("Warning: database has no Version information\n")
elif self._version > PIMP_VERSION:
sys.stderr.write("Warning: database version %s newer than pimp version %s\n"
sys.stderr.write("Warning: database version %s newer than pimp version %s\n"
% (self._version, PIMP_VERSION))
self._maintainer = plistdata.get('Maintainer', '')
self._description = plistdata.get('Description', '').strip()
@ -405,12 +405,12 @@ class PimpDatabase:
others = plistdata.get('Include', [])
for url in others:
self.appendURL(url, included=1)
def _appendPackages(self, packages):
"""Given a list of dictionaries containing package
descriptions create the PimpPackage objects and append them
to our internal storage."""
for p in packages:
p = dict(p)
flavor = p.get('Flavor')
@ -421,27 +421,27 @@ class PimpDatabase:
else:
pkg = PimpPackage(self, dict(p))
self._packages.append(pkg)
def list(self):
"""Return a list of all PimpPackage objects in the database."""
return self._packages
def listnames(self):
"""Return a list of names of all packages in the database."""
rv = []
for pkg in self._packages:
rv.append(pkg.fullname())
rv.sort()
return rv
def dump(self, pathOrFile):
"""Dump the contents of the database to an XML .plist file.
The file can be passed as either a file object or a pathname.
All data, including included databases, is dumped."""
packages = []
for pkg in self._packages:
packages.append(pkg.dump())
@ -453,15 +453,15 @@ class PimpDatabase:
}
plist = plistlib.Plist(**plistdata)
plist.write(pathOrFile)
def find(self, ident):
"""Find a package. The package can be specified by name
or as a dictionary with name, version and flavor entries.
Only name is obligatory. If there are multiple matches the
best one (higher version number, flavors ordered according to
users' preference) is returned."""
if type(ident) == str:
# Remove ( and ) for pseudo-packages
if ident[0] == '(' and ident[-1] == ')':
@ -491,7 +491,7 @@ class PimpDatabase:
if not found or found < p:
found = p
return found
ALLOWED_KEYS = [
"Name",
"Version",
@ -511,7 +511,7 @@ ALLOWED_KEYS = [
class PimpPackage:
"""Class representing a single package."""
def __init__(self, db, plistdata):
self._db = db
name = plistdata["Name"]
@ -519,10 +519,10 @@ class PimpPackage:
if not k in ALLOWED_KEYS:
sys.stderr.write("Warning: %s: unknown key %s\n" % (name, k))
self._dict = plistdata
def __getitem__(self, key):
return self._dict[key]
def name(self): return self._dict['Name']
def version(self): return self._dict.get('Version')
def flavor(self): return self._dict.get('Flavor')
@ -531,13 +531,13 @@ class PimpPackage:
def homepage(self): return self._dict.get('Home-page')
def downloadURL(self): return self._dict.get('Download-URL')
def systemwideOnly(self): return self._dict.get('Systemwide-only')
def fullname(self):
"""Return the full name "name-version-flavor" of a package.
If the package is a pseudo-package, something that cannot be
installed through pimp, return the name in (parentheses)."""
rv = self._dict['Name']
if self._dict.has_key('Version'):
rv = rv + '-%s' % self._dict['Version']
@ -547,14 +547,14 @@ class PimpPackage:
# Pseudo-package, show in parentheses
rv = '(%s)' % rv
return rv
def dump(self):
"""Return a dict object containing the information on the package."""
return self._dict
def __cmp__(self, other):
"""Compare two packages, where the "better" package sorts lower."""
if not isinstance(other, PimpPackage):
return cmp(id(self), id(other))
if self.name() != other.name():
@ -562,15 +562,15 @@ class PimpPackage:
if self.version() != other.version():
return -cmp(self.version(), other.version())
return self._db.preferences.compareFlavors(self.flavor(), other.flavor())
def installed(self):
"""Test wheter the package is installed.
Returns two values: a status indicator which is one of
"yes", "no", "old" (an older version is installed) or "bad"
(something went wrong during the install test) and a human
readable string which may contain more details."""
namespace = {
"NotInstalled": _scriptExc_NotInstalled,
"OldInstalled": _scriptExc_OldInstalled,
@ -602,16 +602,16 @@ class PimpPackage:
sys.stderr.write("-------------------------------------\n")
return "bad", "Package install test got exception"
return "yes", ""
def prerequisites(self):
"""Return a list of prerequisites for this package.
The list contains 2-tuples, of which the first item is either
a PimpPackage object or None, and the second is a descriptive
string. The first item can be None if this package depends on
something that isn't pimp-installable, in which case the descriptive
string should tell the user what to do."""
rv = []
if not self._dict.get('Download-URL'):
# For pseudo-packages that are already installed we don't
@ -619,7 +619,7 @@ class PimpPackage:
status, _ = self.installed()
if status == "yes":
return []
return [(None,
return [(None,
"%s: This package cannot be installed automatically (no Download-URL field)" %
self.fullname())]
if self.systemwideOnly() and self._db.preferences.isUserInstall():
@ -645,28 +645,28 @@ class PimpPackage:
descr = pkg.shortdescription()
rv.append((pkg, descr))
return rv
def downloadPackageOnly(self, output=None):
"""Download a single package, if needed.
An MD5 signature is used to determine whether download is needed,
and to test that we actually downloaded what we expected.
If output is given it is a file-like object that will receive a log
of what happens.
If anything unforeseen happened the method returns an error message
string.
"""
scheme, loc, path, query, frag = urlparse.urlsplit(self._dict['Download-URL'])
path = urllib.url2pathname(path)
filename = os.path.split(path)[1]
self.archiveFilename = os.path.join(self._db.preferences.downloadDir, filename)
self.archiveFilename = os.path.join(self._db.preferences.downloadDir, filename)
if not self._archiveOK():
if scheme == 'manual':
return "Please download package manually and save as %s" % self.archiveFilename
downloader = PimpUrllibDownloader(None, self._db.preferences.downloadDir,
downloader = PimpUrllibDownloader(None, self._db.preferences.downloadDir,
watcher=self._db.preferences.watcher)
if not downloader.download(self._dict['Download-URL'],
self.archiveFilename, output):
@ -675,10 +675,10 @@ class PimpPackage:
return "archive not found after download"
if not self._archiveOK():
return "archive does not have correct MD5 checksum"
def _archiveOK(self):
"""Test an archive. It should exist and the MD5 checksum should be correct."""
if not os.path.exists(self.archiveFilename):
return 0
if not self._dict.get('MD5Sum'):
@ -687,10 +687,10 @@ class PimpPackage:
data = open(self.archiveFilename, 'rb').read()
checksum = md5.new(data).hexdigest()
return checksum == self._dict['MD5Sum']
def unpackPackageOnly(self, output=None):
"""Unpack a downloaded package archive."""
filename = os.path.split(self.archiveFilename)[1]
for ext, unpackerClass, arg in ARCHIVE_FORMATS:
if filename[-len(ext):] == ext:
@ -698,43 +698,43 @@ class PimpPackage:
else:
return "unknown extension for archive file: %s" % filename
self.basename = filename[:-len(ext)]
unpacker = unpackerClass(arg, dir=self._db.preferences.buildDir,
unpacker = unpackerClass(arg, dir=self._db.preferences.buildDir,
watcher=self._db.preferences.watcher)
rv = unpacker.unpack(self.archiveFilename, output=output)
if rv:
return rv
def installPackageOnly(self, output=None):
"""Default install method, to be overridden by subclasses"""
return "%s: This package needs to be installed manually (no support for flavor=\"%s\")" \
% (self.fullname(), self._dict.get(flavor, ""))
def installSinglePackage(self, output=None):
"""Download, unpack and install a single package.
If output is given it should be a file-like object and it
will receive a log of what happened."""
if not self._dict.get('Download-URL'):
return "%s: This package needs to be installed manually (no Download-URL field)" % self.fullname()
msg = self.downloadPackageOnly(output)
if msg:
return "%s: download: %s" % (self.fullname(), msg)
msg = self.unpackPackageOnly(output)
if msg:
return "%s: unpack: %s" % (self.fullname(), msg)
return self.installPackageOnly(output)
def beforeInstall(self):
"""Bookkeeping before installation: remember what we have in site-packages"""
self._old_contents = os.listdir(self._db.preferences.installDir)
def afterInstall(self):
"""Bookkeeping after installation: interpret any new .pth files that have
appeared"""
new_contents = os.listdir(self._db.preferences.installDir)
for fn in new_contents:
if fn in self._old_contents:
@ -757,7 +757,7 @@ class PimpPackage:
line = os.path.join(self._db.preferences.installDir, line)
line = os.path.realpath(line)
if not line in sys.path:
sys.path.append(line)
sys.path.append(line)
def filterExpectedSkips(self, names):
"""Return a list that contains only unpexpected skips"""
@ -780,21 +780,21 @@ class PimpPackage_binary(PimpPackage):
def unpackPackageOnly(self, output=None):
"""We don't unpack binary packages until installing"""
pass
def installPackageOnly(self, output=None):
"""Install a single source package.
If output is given it should be a file-like object and it
will receive a log of what happened."""
if self._dict.has_key('Install-command'):
return "%s: Binary package cannot have Install-command" % self.fullname()
if self._dict.has_key('Pre-install-command'):
if _cmd(output, self._buildDirname, self._dict['Pre-install-command']):
return "pre-install %s: running \"%s\" failed" % \
(self.fullname(), self._dict['Pre-install-command'])
self.beforeInstall()
# Install by unpacking
@ -805,7 +805,7 @@ class PimpPackage_binary(PimpPackage):
else:
return "%s: unknown extension for archive file: %s" % (self.fullname(), filename)
self.basename = filename[:-len(ext)]
install_renames = []
for k, newloc in self._db.preferences.installLocations:
if not newloc:
@ -815,22 +815,22 @@ class PimpPackage_binary(PimpPackage):
else:
return "%s: Don't know installLocation %s" % (self.fullname(), k)
install_renames.append((oldloc, newloc))
unpacker = unpackerClass(arg, dir="/", renames=install_renames)
rv = unpacker.unpack(self.archiveFilename, output=output, package=self)
if rv:
return rv
self.afterInstall()
if self._dict.has_key('Post-install-command'):
if _cmd(output, self._buildDirname, self._dict['Post-install-command']):
return "%s: post-install: running \"%s\" failed" % \
(self.fullname(), self._dict['Post-install-command'])
return None
class PimpPackage_source(PimpPackage):
def unpackPackageOnly(self, output=None):
@ -844,15 +844,15 @@ class PimpPackage_source(PimpPackage):
def installPackageOnly(self, output=None):
"""Install a single source package.
If output is given it should be a file-like object and it
will receive a log of what happened."""
if self._dict.has_key('Pre-install-command'):
if _cmd(output, self._buildDirname, self._dict['Pre-install-command']):
return "pre-install %s: running \"%s\" failed" % \
(self.fullname(), self._dict['Pre-install-command'])
self.beforeInstall()
installcmd = self._dict.get('Install-command')
if installcmd and self._install_renames:
@ -882,45 +882,45 @@ class PimpPackage_source(PimpPackage):
rv = None
shutil.rmtree(unwanted_install_dir)
return rv
self.afterInstall()
if self._dict.has_key('Post-install-command'):
if _cmd(output, self._buildDirname, self._dict['Post-install-command']):
return "post-install %s: running \"%s\" failed" % \
(self.fullname(), self._dict['Post-install-command'])
return None
class PimpInstaller:
"""Installer engine: computes dependencies and installs
packages in the right order."""
def __init__(self, db):
self._todo = []
self._db = db
self._curtodo = []
self._curmessages = []
def __contains__(self, package):
return package in self._todo
def _addPackages(self, packages):
for package in packages:
if not package in self._todo:
self._todo.append(package)
def _prepareInstall(self, package, force=0, recursive=1):
"""Internal routine, recursive engine for prepareInstall.
Test whether the package is installed and (if not installed
or if force==1) prepend it to the temporary todo list and
call ourselves recursively on all prerequisites."""
if not force:
status, message = package.installed()
if status == "yes":
return
return
if package in self._todo or package in self._curtodo:
return
self._curtodo.insert(0, package)
@ -932,17 +932,17 @@ class PimpInstaller:
self._prepareInstall(pkg, False, recursive)
else:
self._curmessages.append("Problem with dependency: %s" % descr)
def prepareInstall(self, package, force=0, recursive=1):
"""Prepare installation of a package.
If the package is already installed and force is false nothing
is done. If recursive is true prerequisites are installed first.
Returns a list of packages (to be passed to install) and a list
of messages of any problems encountered.
"""
self._curtodo = []
self._curmessages = []
self._prepareInstall(package, force, recursive)
@ -950,10 +950,10 @@ class PimpInstaller:
self._curtodo = []
self._curmessages = []
return rv
def install(self, packages, output):
"""Install a list of packages."""
self._addPackages(packages)
status = []
for pkg in self._todo:
@ -961,12 +961,12 @@ class PimpInstaller:
if msg:
status.append(msg)
return status
def _run(mode, verbose, force, args, prefargs, watcher):
"""Engine for the main program"""
prefs = PimpPreferences(**prefargs)
if watcher:
prefs.setWatcher(watcher)
@ -975,7 +975,7 @@ def _run(mode, verbose, force, args, prefargs, watcher):
sys.stdout.write(rv)
db = PimpDatabase(prefs)
db.appendURL(prefs.pimpDatabase)
if mode == 'dump':
db.dump(sys.stdout)
elif mode =='list':
@ -1050,7 +1050,7 @@ def _run(mode, verbose, force, args, prefargs, watcher):
def main():
"""Minimal commandline tool to drive pimp."""
import getopt
def _help():
print "Usage: pimp [options] -s [package ...] List installed status"
@ -1065,12 +1065,12 @@ def main():
print " (default: %s)" % DEFAULT_INSTALLDIR
print " -u url URL for database"
sys.exit(1)
class _Watcher:
def update(self, msg):
sys.stderr.write(msg + '\r')
return 1
try:
opts, args = getopt.getopt(sys.argv[1:], "slifvdD:Vu:")
except getopt.GetoptError:
@ -1133,8 +1133,6 @@ if __name__ != 'pimp_update':
(pimp_update.PIMP_VERSION, PIMP_VERSION))
else:
from pimp_update import *
if __name__ == '__main__':
main()