Commit 6d3753cc authored by PJ Eby's avatar PJ Eby

Rough draft of version requirement parser. Make bdist_egg look for a

distname.egg-info directory instead of EGG-INFO.in; this will be used later
to support development of egg-distributed packages that an application
under development expects to 'require()'.  (Thanks to Fred Drake for
pointing out this use case, and Bob Ippolito for helping me figure out how
to support it, although the runtime support doesn't actually exist yet.)

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4040999
parent 0ad2e2ea
This diff is collapsed.
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
Build .egg distributions""" Build .egg distributions"""
# This module should be kept compatible with Python 2.3 # This module should be kept compatible with Python 2.3
import os import os
from distutils.core import Command from distutils.core import Command
from distutils.util import get_platform from distutils.util import get_platform
...@@ -11,14 +10,15 @@ from distutils.dir_util import create_tree, remove_tree, ensure_relative,mkpath ...@@ -11,14 +10,15 @@ from distutils.dir_util import create_tree, remove_tree, ensure_relative,mkpath
from distutils.sysconfig import get_python_version from distutils.sysconfig import get_python_version
from distutils.errors import * from distutils.errors import *
from distutils import log from distutils import log
from pkg_resources import parse_requirements
class bdist_egg(Command): class bdist_egg(Command):
description = "create an \"egg\" distribution" description = "create an \"egg\" distribution"
user_options = [('egg-info=', 'e', user_options = [('egg-base=', 'e',
"directory containing EGG-INFO for the distribution " "directory containing .egg-info directories"
"(default: EGG-INFO.in)"), "(default: top of the source tree)"),
('bdist-dir=', 'd', ('bdist-dir=', 'd',
"temporary directory for creating the distribution"), "temporary directory for creating the distribution"),
('plat-name=', 'p', ('plat-name=', 'p',
...@@ -40,6 +40,9 @@ class bdist_egg(Command): ...@@ -40,6 +40,9 @@ class bdist_egg(Command):
def initialize_options (self): def initialize_options (self):
self.egg_name = None
self.egg_version = None
self.egg_base = None
self.egg_info = None self.egg_info = None
self.bdist_dir = None self.bdist_dir = None
self.plat_name = None self.plat_name = None
...@@ -47,27 +50,35 @@ class bdist_egg(Command): ...@@ -47,27 +50,35 @@ class bdist_egg(Command):
self.dist_dir = None self.dist_dir = None
self.skip_build = 0 self.skip_build = 0
self.relative = 0 self.relative = 0
# initialize_options()
def finalize_options (self): def finalize_options (self):
self.egg_name = self.distribution.get_name().replace('-','_')
if self.egg_info is None and os.path.isdir('EGG-INFO.in'): self.egg_version = self.distribution.get_version().replace('-','_')
self.egg_info = 'EGG-INFO.in' try:
list(
elif self.egg_info: parse_requirements('%s==%s' % (self.egg_name,self.egg_version))
self.ensure_dirname('egg_info') )
except ValueError:
raise DistutilsOptionError(
"Invalid distribution name or version syntax: %s-%s" %
(self.egg_name,self.egg_version)
)
if self.egg_base is None:
dirs = self.distribution.package_dir
self.egg_base = (dirs or {}).get('','.')
self.ensure_dirname('egg_base')
self.egg_info = os.path.join(
self.egg_base, self.egg_name+'.egg-info'
)
if self.bdist_dir is None: if self.bdist_dir is None:
bdist_base = self.get_finalized_command('bdist').bdist_base bdist_base = self.get_finalized_command('bdist').bdist_base
self.bdist_dir = os.path.join(bdist_base, 'egg') self.bdist_dir = os.path.join(bdist_base, 'egg')
self.set_undefined_options('bdist', self.set_undefined_options('bdist',
('dist_dir', 'dist_dir'), ('dist_dir', 'dist_dir'),
('plat_name', 'plat_name')) ('plat_name', 'plat_name'))
# finalize_options()
def write_stub(self, resource, pyfile): def write_stub(self, resource, pyfile):
f = open(pyfile,'w') f = open(pyfile,'w')
...@@ -84,9 +95,33 @@ class bdist_egg(Command): ...@@ -84,9 +95,33 @@ class bdist_egg(Command):
])) ]))
f.close() f.close()
def run (self):
def run(self):
if not self.skip_build: if not self.skip_build:
self.run_command('build') self.run_command('build')
...@@ -113,46 +148,50 @@ class bdist_egg(Command): ...@@ -113,46 +148,50 @@ class bdist_egg(Command):
if to_compile: if to_compile:
install.byte_compile(to_compile) install.byte_compile(to_compile)
# And make an archive relative to the root of the # And make an archive relative to the root of the
# pseudo-installation tree. # pseudo-installation tree.
archive_basename = "%s-py%s" % (self.distribution.get_fullname(), archive_basename = "%s-%s-py%s" % (self.egg_name, self.egg_version,
get_python_version()) get_python_version())
if ext_outputs: if ext_outputs:
archive_basename += "-" + self.plat_name archive_basename += "-" + self.plat_name
# OS/2 objects to any ":" characters in a filename (such as when # OS/2 objects to any ":" characters in a filename (such as when
# a timestamp is used in a version) so change them to hyphens. # a timestamp is used in a version) so change them to underscores.
if os.name == "os2": if os.name == "os2":
archive_basename = archive_basename.replace(":", "-") archive_basename = archive_basename.replace(":", "_")
pseudoinstall_root = os.path.join(self.dist_dir, archive_basename) pseudoinstall_root = os.path.join(self.dist_dir, archive_basename)
archive_root = self.bdist_dir archive_root = self.bdist_dir
# Make the EGG-INFO directory # Make the EGG-INFO directory
log.info("creating EGG-INFO directory")
egg_info = os.path.join(archive_root,'EGG-INFO') egg_info = os.path.join(archive_root,'EGG-INFO')
self.mkpath(egg_info) self.mkpath(egg_info)
self.mkpath(self.egg_info)
if self.egg_info: log.info("writing %s" % os.path.join(self.egg_info,'PKG-INFO'))
for filename in os.listdir(self.egg_info):
path = os.path.join(self.egg_info,filename)
if os.path.isfile(path):
self.copy_file(path,os.path.join(egg_info,filename))
log.info("writing EGG-INFO/PKG-INFO")
if not self.dry_run: if not self.dry_run:
self.distribution.metadata.write_pkg_info(egg_info) self.distribution.metadata.write_pkg_info(self.egg_info)
native_libs = os.path.join(self.egg_info,"native_libs.txt")
if ext_outputs: if ext_outputs:
log.info("writing EGG-INFO/native_libs.txt") log.info("writing %s" % native_libs)
if not self.dry_run: if not self.dry_run:
libs_file = open( libs_file = open(native_libs, 'wt')
os.path.join(egg_info,"native_libs.txt"),'wt')
libs_file.write('\n'.join(ext_outputs)) libs_file.write('\n'.join(ext_outputs))
libs_file.write('\n') libs_file.write('\n')
libs_file.close() libs_file.close()
elif os.path.isfile(native_libs):
log.info("removing %s" % native_libs)
if not self.dry_run:
os.unlink(native_libs)
if self.egg_info:
for filename in os.listdir(self.egg_info):
path = os.path.join(self.egg_info,filename)
if os.path.isfile(path):
self.copy_file(path,os.path.join(egg_info,filename))
# Make the archive # Make the archive
make_zipfile(pseudoinstall_root+'.egg', make_zipfile(pseudoinstall_root+'.egg',
...@@ -162,10 +201,6 @@ class bdist_egg(Command): ...@@ -162,10 +201,6 @@ class bdist_egg(Command):
if not self.keep_temp: if not self.keep_temp:
remove_tree(self.bdist_dir, dry_run=self.dry_run) remove_tree(self.bdist_dir, dry_run=self.dry_run)
# run()
# class bdist_egg
def make_zipfile (zip_filename, base_dir, verbose=0, dry_run=0): def make_zipfile (zip_filename, base_dir, verbose=0, dry_run=0):
...@@ -176,7 +211,7 @@ def make_zipfile (zip_filename, base_dir, verbose=0, dry_run=0): ...@@ -176,7 +211,7 @@ def make_zipfile (zip_filename, base_dir, verbose=0, dry_run=0):
raises DistutilsExecError. Returns the name of the output zip file. raises DistutilsExecError. Returns the name of the output zip file.
""" """
import zipfile import zipfile
mkpath(os.path.dirname(zip_filename), dry_run=dry_run) mkpath(os.path.dirname(zip_filename), dry_run=dry_run)
# If zipfile module is not available, try spawning an external # If zipfile module is not available, try spawning an external
...@@ -203,3 +238,9 @@ def make_zipfile (zip_filename, base_dir, verbose=0, dry_run=0): ...@@ -203,3 +238,9 @@ def make_zipfile (zip_filename, base_dir, verbose=0, dry_run=0):
# make_zipfile () # make_zipfile ()
"""Tests for the 'setuptools' package""" """Tests for the 'setuptools' package"""
from unittest import TestSuite, TestCase, makeSuite from unittest import TestSuite, TestCase, makeSuite, defaultTestLoader
import distutils.core, distutils.cmd import distutils.core, distutils.cmd
from distutils.errors import DistutilsOptionError, DistutilsPlatformError from distutils.errors import DistutilsOptionError, DistutilsPlatformError
from distutils.errors import DistutilsSetupError from distutils.errors import DistutilsSetupError
...@@ -409,13 +409,13 @@ class TestCommandTests(TestCase): ...@@ -409,13 +409,13 @@ class TestCommandTests(TestCase):
testClasses = (DependsTests, DistroTests, FeatureTests, TestCommandTests) testClasses = (DependsTests, DistroTests, FeatureTests, TestCommandTests)
testNames = ["setuptools.tests.test_resources"]
def test_suite(): def test_suite():
return TestSuite([makeSuite(t,'test') for t in testClasses]) return TestSuite(
[makeSuite(t,'test') for t in testClasses]+
[defaultTestLoader.loadTestsFromName(n) for n in testNames]
)
......
from unittest import TestCase, makeSuite
from pkg_resources import *
import pkg_resources
class DistroTests(TestCase):
def testEmptyiter(self):
# empty path should produce no distributions
self.assertEqual(list(iter_distributions(path=[])), [])
class ParseTests(TestCase):
def testEmptyParse(self):
self.assertEqual(list(parse_requirements('')), [])
def testYielding(self):
for inp,out in [
([], []), ('x',['x']), ([[]],[]), (' x\n y', ['x','y']),
(['x\n\n','y'], ['x','y']),
]:
self.assertEqual(list(pkg_resources.yield_lines(inp)),out)
def testSimple(self):
self.assertEqual(
list(parse_requirements('Twis-Ted>=1.2')),
[('Twis_Ted',[('>=','1.2')])]
)
self.assertEqual(
list(parse_requirements('Twisted >=1.2, \ # more\n<2.0')),
[('Twisted',[('>=','1.2'),('<','2.0')])]
)
self.assertRaises(ValueError,lambda:list(parse_requirements(">=2.3")))
self.assertRaises(ValueError,lambda:list(parse_requirements("x\\")))
self.assertRaises(ValueError,lambda:list(parse_requirements("x==2 q")))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment