[Python-checkins] python/dist/src/Lib/distutils versionpredicate.py, NONE, 1.4.2.2 core.py, 1.50.2.2, 1.50.2.3 dir_util.py, 1.9.2.2, 1.9.2.3 dist.py, 1.55.2.2, 1.55.2.3 msvccompiler.py, 1.49.2.2, 1.49.2.3 sysconfig.py, 1.49.2.4, 1.49.2.5
jhylton@users.sourceforge.net
jhylton at users.sourceforge.net
Sun Oct 16 07:24:33 CEST 2005
Update of /cvsroot/python/python/dist/src/Lib/distutils
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Lib/distutils
Modified Files:
Tag: ast-branch
core.py dir_util.py dist.py msvccompiler.py sysconfig.py
Added Files:
Tag: ast-branch
versionpredicate.py
Log Message:
Merge head to branch (for the last time)
--- NEW FILE: versionpredicate.py ---
"""Module for parsing and testing package version predicate strings.
"""
import re
import distutils.version
import operator
re_validPackage = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)")
# (package) (rest)
re_paren = re.compile(r"^\s*\((.*)\)\s*$") # (list) inside of parentheses
re_splitComparison = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$")
# (comp) (version)
def splitUp(pred):
"""Parse a single version comparison.
Return (comparison string, StrictVersion)
"""
res = re_splitComparison.match(pred)
if not res:
raise ValueError("bad package restriction syntax: %r" % pred)
comp, verStr = res.groups()
return (comp, distutils.version.StrictVersion(verStr))
compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq,
">": operator.gt, ">=": operator.ge, "!=": operator.ne}
class VersionPredicate:
"""Parse and test package version predicates.
>>> v = VersionPredicate('pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)')
The `name` attribute provides the full dotted name that is given::
>>> v.name
'pyepat.abc'
The str() of a `VersionPredicate` provides a normalized
human-readable version of the expression::
>>> print v
pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3)
The `satisfied_by()` method can be used to determine with a given
version number is included in the set described by the version
restrictions::
>>> v.satisfied_by('1.1')
True
>>> v.satisfied_by('1.4')
True
>>> v.satisfied_by('1.0')
False
>>> v.satisfied_by('4444.4')
False
>>> v.satisfied_by('1555.1b3')
False
`VersionPredicate` is flexible in accepting extra whitespace::
>>> v = VersionPredicate(' pat( == 0.1 ) ')
>>> v.name
'pat'
>>> v.satisfied_by('0.1')
True
>>> v.satisfied_by('0.2')
False
If any version numbers passed in do not conform to the
restrictions of `StrictVersion`, a `ValueError` is raised::
>>> v = VersionPredicate('p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)')
Traceback (most recent call last):
...
ValueError: invalid version number '1.2zb3'
It the module or package name given does not conform to what's
allowed as a legal module or package name, `ValueError` is
raised::
>>> v = VersionPredicate('foo-bar')
Traceback (most recent call last):
...
ValueError: expected parenthesized list: '-bar'
>>> v = VersionPredicate('foo bar (12.21)')
Traceback (most recent call last):
...
ValueError: expected parenthesized list: 'bar (12.21)'
"""
def __init__(self, versionPredicateStr):
"""Parse a version predicate string.
"""
# Fields:
# name: package name
# pred: list of (comparison string, StrictVersion)
versionPredicateStr = versionPredicateStr.strip()
if not versionPredicateStr:
raise ValueError("empty package restriction")
match = re_validPackage.match(versionPredicateStr)
if not match:
raise ValueError("bad package name in %r" % versionPredicateStr)
self.name, paren = match.groups()
paren = paren.strip()
if paren:
match = re_paren.match(paren)
if not match:
raise ValueError("expected parenthesized list: %r" % paren)
str = match.groups()[0]
self.pred = [splitUp(aPred) for aPred in str.split(",")]
if not self.pred:
raise ValueError("empty parenthesized list in %r"
% versionPredicateStr)
else:
self.pred = []
def __str__(self):
if self.pred:
seq = [cond + " " + str(ver) for cond, ver in self.pred]
return self.name + " (" + ", ".join(seq) + ")"
else:
return self.name
def satisfied_by(self, version):
"""True if version is compatible with all the predicates in self.
The parameter version must be acceptable to the StrictVersion
constructor. It may be either a string or StrictVersion.
"""
for cond, ver in self.pred:
if not compmap[cond](version, ver):
return False
return True
_provision_rx = None
def split_provision(value):
"""Return the name and optional version number of a provision.
The version number, if given, will be returned as a `StrictVersion`
instance, otherwise it will be `None`.
>>> split_provision('mypkg')
('mypkg', None)
>>> split_provision(' mypkg( 1.2 ) ')
('mypkg', StrictVersion ('1.2'))
"""
global _provision_rx
if _provision_rx is None:
_provision_rx = re.compile(
"([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(?:\s*\(\s*([^)\s]+)\s*\))?$")
value = value.strip()
m = _provision_rx.match(value)
if not m:
raise ValueError("illegal provides specification: %r" % value)
ver = m.group(2) or None
if ver:
ver = distutils.version.StrictVersion(ver)
return m.group(1), ver
Index: core.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/distutils/core.py,v
retrieving revision 1.50.2.2
retrieving revision 1.50.2.3
diff -u -d -r1.50.2.2 -r1.50.2.3
--- core.py 7 Jan 2005 06:58:15 -0000 1.50.2.2
+++ core.py 16 Oct 2005 05:24:00 -0000 1.50.2.3
@@ -47,7 +47,9 @@
'name', 'version', 'author', 'author_email',
'maintainer', 'maintainer_email', 'url', 'license',
'description', 'long_description', 'keywords',
- 'platforms', 'classifiers', 'download_url',)
+ 'platforms', 'classifiers', 'download_url',
+ 'requires', 'provides', 'obsoletes',
+ )
# Legal keyword arguments for the Extension constructor
extension_keywords = ('name', 'sources', 'include_dirs',
Index: dir_util.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/distutils/dir_util.py,v
retrieving revision 1.9.2.2
retrieving revision 1.9.2.3
diff -u -d -r1.9.2.2 -r1.9.2.3
--- dir_util.py 7 Jan 2005 06:58:16 -0000 1.9.2.2
+++ dir_util.py 16 Oct 2005 05:24:00 -0000 1.9.2.3
@@ -31,7 +31,7 @@
global _path_created
# Detect a common bug -- name is None
- if type(name) is not StringType:
+ if not isinstance(name, StringTypes):
raise DistutilsInternalError, \
"mkpath: 'name' must be a string (got %r)" % (name,)
Index: dist.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/distutils/dist.py,v
retrieving revision 1.55.2.2
retrieving revision 1.55.2.3
diff -u -d -r1.55.2.2 -r1.55.2.3
--- dist.py 7 Jan 2005 06:58:16 -0000 1.55.2.2
+++ dist.py 16 Oct 2005 05:24:00 -0000 1.55.2.3
@@ -59,6 +59,15 @@
('help', 'h', "show detailed help message"),
]
+ # 'common_usage' is a short (2-3 line) string describing the common
+ # usage of the setup script.
+ common_usage = """\
+Common commands: (see '--help-commands' for more)
+
+ setup.py build will build the package underneath 'build/'
+ setup.py install will install the package
+"""
+
# options that are not propagated to the commands
display_options = [
('help-commands', None,
@@ -97,6 +106,12 @@
"print the list of classifiers"),
('keywords', None,
"print the list of keywords"),
+ ('provides', None,
+ "print the list of packages/modules provided"),
+ ('requires', None,
+ "print the list of packages/modules required"),
+ ('obsoletes', None,
+ "print the list of packages/modules made obsolete")
]
display_option_names = map(lambda x: translate_longopt(x[0]),
display_options)
@@ -162,6 +177,17 @@
# command_options = { command_name : { option : (source, value) } }
self.command_options = {}
+ # 'dist_files' is the list of (command, pyversion, file) that
+ # have been created by any dist commands run so far. This is
+ # filled regardless of whether the run is dry or not. pyversion
+ # gives sysconfig.get_python_version() if the dist file is
+ # specific to a Python version, 'any' if it is good for all
+ # Python versions on the target platform, and '' for a source
+ # file. pyversion should not be used to specify minimum or
+ # maximum required Python versions; use the metainfo for that
+ # instead.
+ self.dist_files = []
+
# These options are really the business of various commands, rather
# than of the Distribution itself. We provide aliases for them in
# Distribution as a convenience to the developer.
@@ -201,7 +227,6 @@
# distribution options.
if attrs:
-
# Pull out the set of command options and work on them
# specifically. Note that this order guarantees that aliased
# command options will override any supplied redundantly
@@ -226,7 +251,9 @@
# Now work on the rest of the attributes. Any attribute that's
# not already defined is invalid!
for (key,val) in attrs.items():
- if hasattr(self.metadata, key):
+ if hasattr(self.metadata, "set_" + key):
+ getattr(self.metadata, "set_" + key)(val)
+ elif hasattr(self.metadata, key):
setattr(self.metadata, key, val)
elif hasattr(self, key):
setattr(self, key, val)
@@ -608,7 +635,7 @@
else:
options = self.global_options
parser.set_option_table(options)
- parser.print_help("Global options:")
+ parser.print_help(self.common_usage + "\nGlobal options:")
print
if display_options:
@@ -669,7 +696,8 @@
value = getattr(self.metadata, "get_"+opt)()
if opt in ['keywords', 'platforms']:
print string.join(value, ',')
- elif opt == 'classifiers':
+ elif opt in ('classifiers', 'provides', 'requires',
+ 'obsoletes'):
print string.join(value, '\n')
else:
print value
@@ -1015,7 +1043,10 @@
"license", "description", "long_description",
"keywords", "platforms", "fullname", "contact",
"contact_email", "license", "classifiers",
- "download_url")
+ "download_url",
+ # PEP 314
+ "provides", "requires", "obsoletes",
+ )
def __init__ (self):
self.name = None
@@ -1032,40 +1063,58 @@
self.platforms = None
self.classifiers = None
self.download_url = None
+ # PEP 314
+ self.provides = None
+ self.requires = None
+ self.obsoletes = None
def write_pkg_info (self, base_dir):
"""Write the PKG-INFO file into the release tree.
"""
-
pkg_info = open( os.path.join(base_dir, 'PKG-INFO'), 'w')
- pkg_info.write('Metadata-Version: 1.0\n')
- pkg_info.write('Name: %s\n' % self.get_name() )
- pkg_info.write('Version: %s\n' % self.get_version() )
- pkg_info.write('Summary: %s\n' % self.get_description() )
- pkg_info.write('Home-page: %s\n' % self.get_url() )
- pkg_info.write('Author: %s\n' % self.get_contact() )
- pkg_info.write('Author-email: %s\n' % self.get_contact_email() )
- pkg_info.write('License: %s\n' % self.get_license() )
+ self.write_pkg_file(pkg_info)
+
+ pkg_info.close()
+
+ # write_pkg_info ()
+
+ def write_pkg_file (self, file):
+ """Write the PKG-INFO format data to a file object.
+ """
+ version = '1.0'
+ if self.provides or self.requires or self.obsoletes:
+ version = '1.1'
+
+ file.write('Metadata-Version: %s\n' % version)
+ file.write('Name: %s\n' % self.get_name() )
+ file.write('Version: %s\n' % self.get_version() )
+ file.write('Summary: %s\n' % self.get_description() )
+ file.write('Home-page: %s\n' % self.get_url() )
+ file.write('Author: %s\n' % self.get_contact() )
+ file.write('Author-email: %s\n' % self.get_contact_email() )
+ file.write('License: %s\n' % self.get_license() )
if self.download_url:
- pkg_info.write('Download-URL: %s\n' % self.download_url)
+ file.write('Download-URL: %s\n' % self.download_url)
long_desc = rfc822_escape( self.get_long_description() )
- pkg_info.write('Description: %s\n' % long_desc)
+ file.write('Description: %s\n' % long_desc)
keywords = string.join( self.get_keywords(), ',')
if keywords:
- pkg_info.write('Keywords: %s\n' % keywords )
-
- for platform in self.get_platforms():
- pkg_info.write('Platform: %s\n' % platform )
+ file.write('Keywords: %s\n' % keywords )
- for classifier in self.get_classifiers():
- pkg_info.write('Classifier: %s\n' % classifier )
+ self._write_list(file, 'Platform', self.get_platforms())
+ self._write_list(file, 'Classifier', self.get_classifiers())
- pkg_info.close()
+ # PEP 314
+ self._write_list(file, 'Requires', self.get_requires())
+ self._write_list(file, 'Provides', self.get_provides())
+ self._write_list(file, 'Obsoletes', self.get_obsoletes())
- # write_pkg_info ()
+ def _write_list (self, file, name, values):
+ for value in values:
+ file.write('%s: %s\n' % (name, value))
# -- Metadata query methods ----------------------------------------
@@ -1125,6 +1174,36 @@
def get_download_url(self):
return self.download_url or "UNKNOWN"
+ # PEP 314
+
+ def get_requires(self):
+ return self.requires or []
+
+ def set_requires(self, value):
+ import distutils.versionpredicate
+ for v in value:
+ distutils.versionpredicate.VersionPredicate(v)
+ self.requires = value
+
+ def get_provides(self):
+ return self.provides or []
+
+ def set_provides(self, value):
+ value = [v.strip() for v in value]
+ for v in value:
+ import distutils.versionpredicate
+ distutils.versionpredicate.split_provision(v)
+ self.provides = value
+
+ def get_obsoletes(self):
+ return self.obsoletes or []
+
+ def set_obsoletes(self, value):
+ import distutils.versionpredicate
+ for v in value:
+ distutils.versionpredicate.VersionPredicate(v)
+ self.obsoletes = value
+
# class DistributionMetadata
Index: msvccompiler.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/distutils/msvccompiler.py,v
retrieving revision 1.49.2.2
retrieving revision 1.49.2.3
diff -u -d -r1.49.2.2 -r1.49.2.3
--- msvccompiler.py 7 Jan 2005 06:58:16 -0000 1.49.2.2
+++ msvccompiler.py 16 Oct 2005 05:24:00 -0000 1.49.2.3
@@ -211,6 +211,9 @@
self.__macros = MacroExpander(self.__version)
else:
self.__root = r"Software\Microsoft\Devstudio"
+ self.initialized = False
+
+ def initialize(self):
self.__paths = self.get_msvc_paths("path")
if len (self.__paths) == 0:
@@ -252,6 +255,7 @@
]
self.ldflags_static = [ '/nologo']
+ self.initialized = True
# -- Worker methods ------------------------------------------------
@@ -265,6 +269,8 @@
obj_names = []
for src_name in source_filenames:
(base, ext) = os.path.splitext (src_name)
+ base = os.path.splitdrive(base)[1] # Chop off the drive
+ base = base[os.path.isabs(base):] # If abs, chop off leading /
if ext not in self.src_extensions:
# Better to raise an exception instead of silently continuing
# and later complain about sources and targets having
@@ -290,6 +296,7 @@
output_dir=None, macros=None, include_dirs=None, debug=0,
extra_preargs=None, extra_postargs=None, depends=None):
+ if not self.initialized: self.initialize()
macros, objects, extra_postargs, pp_opts, build = \
self._setup_compile(output_dir, macros, include_dirs, sources,
depends, extra_postargs)
@@ -381,6 +388,7 @@
debug=0,
target_lang=None):
+ if not self.initialized: self.initialize()
(objects, output_dir) = self._fix_object_args (objects, output_dir)
output_filename = \
self.library_filename (output_libname, output_dir=output_dir)
@@ -414,6 +422,7 @@
build_temp=None,
target_lang=None):
+ if not self.initialized: self.initialize()
(objects, output_dir) = self._fix_object_args (objects, output_dir)
(libraries, library_dirs, runtime_library_dirs) = \
self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
Index: sysconfig.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/distutils/sysconfig.py,v
retrieving revision 1.49.2.4
retrieving revision 1.49.2.5
diff -u -d -r1.49.2.4 -r1.49.2.5
--- sysconfig.py 7 Jan 2005 06:58:16 -0000 1.49.2.4
+++ sysconfig.py 16 Oct 2005 05:24:00 -0000 1.49.2.5
@@ -34,7 +34,7 @@
del argv0_path, landmark
-def get_python_version ():
+def get_python_version():
"""Return a string containing the major and minor Python version,
leaving off the patchlevel. Sample return values could be '1.5'
or '2.2'.
@@ -65,7 +65,7 @@
if not os.path.exists(inc_dir):
inc_dir = os.path.join(os.path.dirname(base), "Include")
return inc_dir
- return os.path.join(prefix, "include", "python" + sys.version[:3])
+ return os.path.join(prefix, "include", "python" + get_python_version())
elif os.name == "nt":
return os.path.join(prefix, "include")
elif os.name == "mac":
@@ -110,7 +110,7 @@
if standard_lib:
return os.path.join(prefix, "Lib")
else:
- if sys.version < "2.2":
+ if get_python_version() < "2.2":
return prefix
else:
return os.path.join(PREFIX, "Lib", "site-packages")
@@ -146,8 +146,9 @@
varies across Unices and is stored in Python's Makefile.
"""
if compiler.compiler_type == "unix":
- (cc, cxx, opt, basecflags, ccshared, ldshared, so_ext) = \
- get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS', 'CCSHARED', 'LDSHARED', 'SO')
+ (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \
+ get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
+ 'CCSHARED', 'LDSHARED', 'SO')
if os.environ.has_key('CC'):
cc = os.environ['CC']
@@ -161,17 +162,15 @@
cpp = cc + " -E" # not always
if os.environ.has_key('LDFLAGS'):
ldshared = ldshared + ' ' + os.environ['LDFLAGS']
- if basecflags:
- opt = basecflags + ' ' + opt
if os.environ.has_key('CFLAGS'):
- opt = opt + ' ' + os.environ['CFLAGS']
+ cflags = opt + ' ' + os.environ['CFLAGS']
ldshared = ldshared + ' ' + os.environ['CFLAGS']
if os.environ.has_key('CPPFLAGS'):
cpp = cpp + ' ' + os.environ['CPPFLAGS']
- opt = opt + ' ' + os.environ['CPPFLAGS']
+ cflags = cflags + ' ' + os.environ['CPPFLAGS']
ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
- cc_cmd = cc + ' ' + opt
+ cc_cmd = cc + ' ' + cflags
compiler.set_executables(
preprocessor=cpp,
compiler=cc_cmd,
@@ -189,7 +188,7 @@
inc_dir = os.curdir
else:
inc_dir = get_python_inc(plat_specific=1)
- if sys.version < '2.2':
+ if get_python_version() < '2.2':
config_h = 'config.h'
else:
# The name of the config.h file changed in 2.2
@@ -277,25 +276,20 @@
m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
if m:
n = m.group(1)
+ found = True
if done.has_key(n):
- after = value[m.end():]
- value = value[:m.start()] + str(done[n]) + after
- if "$" in after:
- notdone[name] = value
- else:
- try: value = int(value)
- except ValueError:
- done[name] = string.strip(value)
- else:
- done[name] = value
- del notdone[name]
+ item = str(done[n])
elif notdone.has_key(n):
# get it on a subsequent round
- pass
+ found = False
+ elif os.environ.has_key(n):
+ # do it like make: fall back to environment
+ item = os.environ[n]
else:
- done[n] = ""
+ done[n] = item = ""
+ if found:
after = value[m.end():]
- value = value[:m.start()] + after
+ value = value[:m.start()] + item + after
if "$" in after:
notdone[name] = value
else:
@@ -378,7 +372,7 @@
if python_build:
g['LDSHARED'] = g['BLDSHARED']
- elif sys.version < '2.1':
+ elif get_python_version() < '2.1':
# The following two branches are for 1.5.2 compatibility.
if sys.platform == 'aix4': # what about AIX 3.x ?
# Linker script is in the config directory, not in Modules as the
@@ -405,7 +399,7 @@
# it's taken care of for them by the 'build_ext.get_libraries()'
# method.)
g['LDSHARED'] = ("%s -L%s/lib -lpython%s" %
- (linkerscript, PREFIX, sys.version[0:3]))
+ (linkerscript, PREFIX, get_python_version()))
global _config_vars
_config_vars = g
More information about the Python-checkins
mailing list