summaryrefslogtreecommitdiff
path: root/setuptools
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools')
-rw-r--r--setuptools/command/__init__.py13
-rwxr-xr-xsetuptools/command/egg_info.py38
-rw-r--r--setuptools/dist.py69
-rw-r--r--setuptools/tests/test_resources.py84
4 files changed, 160 insertions, 44 deletions
diff --git a/setuptools/command/__init__.py b/setuptools/command/__init__.py
index 29f3000d..a58b5344 100644
--- a/setuptools/command/__init__.py
+++ b/setuptools/command/__init__.py
@@ -1,17 +1,10 @@
-import distutils.command
-
__all__ = [
- 'test', 'develop', 'bdist_egg', 'saveopts', 'setopt', 'rotate', 'alias'
+ 'alias', 'bdist_egg', 'build_ext', 'build_py', 'depends', 'develop',
+ 'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts',
+ 'sdist', 'setopt', 'test', 'upload',
]
-# Make our commands available as though they were part of the distutils
-
-distutils.command.__path__.extend(__path__)
-distutils.command.__all__.extend(
- [cmd for cmd in __all__ if cmd not in distutils.command.__all__]
- )
-
from distutils.command.bdist import bdist
if 'egg' not in bdist.format_commands:
diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index a5418568..8577230f 100755
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -8,7 +8,7 @@ from setuptools import Command
from distutils.errors import *
from distutils import log
from pkg_resources import parse_requirements, safe_name, \
- safe_version, yield_lines
+ safe_version, yield_lines, EntryPoint
from setuptools.dist import iter_distribution_names
class egg_info(Command):
@@ -95,7 +95,7 @@ class egg_info(Command):
metadata.write_pkg_info(self.egg_info)
finally:
metadata.name, metadata.version = oldname, oldver
-
+ self.write_entry_points()
self.write_requirements()
self.write_toplevel_names()
self.write_or_delete_dist_arg('namespace_packages')
@@ -183,23 +183,23 @@ class egg_info(Command):
if not self.dry_run:
os.unlink(filename)
+ def write_entry_points(self):
+ ep = getattr(self.distribution,'entry_points',None)
+ if ep is None:
+ return
+ epname = os.path.join(self.egg_info,"entry_points.txt")
+ log.info("writing %s", epname)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ if not self.dry_run:
+ f = open(epname, 'wt')
+ if isinstance(ep,basestring):
+ f.write(ep)
+ else:
+ for section, contents in ep.items():
+ if not isinstance(contents,basestring):
+ contents = EntryPoint.parse_list(section, contents)
+ contents = '\n'.join(map(str,contents.values()))
+ f.write('[%s]\n%s\n\n' % (section,contents))
+ f.close()
diff --git a/setuptools/dist.py b/setuptools/dist.py
index 3c7ff852..a603ade0 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -11,6 +11,32 @@ from distutils.errors import DistutilsOptionError, DistutilsPlatformError
from distutils.errors import DistutilsSetupError
import setuptools, pkg_resources
+def get_command_class(self, command):
+ """Pluggable version of get_command_class()"""
+ if command in self.cmdclass:
+ return self.cmdclass[command]
+
+ for dist in pkg_resources.working_set:
+ if dist.get_entry_info('distutils.commands',command):
+ cmdclass = dist.load_entry_point('distutils.commands',command)
+ self.cmdclass[command] = cmdclass
+ return cmdclass
+ else:
+ return _old_get_command_class(self, command)
+
+def print_commands(self):
+ for dist in pkg_resources.working_set:
+ for cmd,ep in dist.get_entry_map('distutils.commands').items():
+ if cmd not in self.cmdclass:
+ cmdclass = ep.load() # don't require extras, we're not running
+ self.cmdclass[cmd] = cmdclass
+ return _old_print_commands(self)
+
+for meth in 'print_commands', 'get_command_class':
+ if getattr(_Distribution,meth).im_func.func_globals is not globals():
+ globals()['_old_'+meth] = getattr(_Distribution,meth)
+ setattr(_Distribution, meth, globals()[meth])
+
sequence = tuple, list
class Distribution(_Distribution):
@@ -80,6 +106,21 @@ class Distribution(_Distribution):
distribution for the included and excluded features.
"""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
def __init__ (self, attrs=None):
have_package_data = hasattr(self, "package_data")
if not have_package_data:
@@ -93,15 +134,9 @@ class Distribution(_Distribution):
self.zip_safe = None
self.namespace_packages = None
self.eager_resources = None
+ self.entry_points = None
_Distribution.__init__(self,attrs)
- if not have_package_data:
- from setuptools.command.build_py import build_py
- self.cmdclass.setdefault('build_py',build_py)
- self.cmdclass.setdefault('build_ext',build_ext)
- self.cmdclass.setdefault('install',install)
- self.cmdclass.setdefault('install_lib',install_lib)
- self.cmdclass.setdefault('sdist',sdist)
def parse_command_line(self):
"""Process features after parsing command line options"""
@@ -121,6 +156,12 @@ class Distribution(_Distribution):
+
+
+
+
+
+
def finalize_options(self):
_Distribution.finalize_options(self)
@@ -171,6 +212,12 @@ class Distribution(_Distribution):
"namespace package %r" % nsp
)
+ if self.entry_points is not None:
+ try:
+ pkg_resources.EntryPoint.parse_map(self.entry_points)
+ except ValueError, e:
+ raise DistutilsSetupError(e)
+
def _set_global_opts_from_features(self):
"""Add --with-X/--without-X options based on optional features"""
@@ -197,12 +244,6 @@ class Distribution(_Distribution):
-
-
-
-
-
-
def _finalize_features(self):
"""Add/remove features and resolve dependencies between them"""
@@ -420,7 +461,7 @@ class Distribution(_Distribution):
src,alias = aliases[command]
del aliases[command] # ensure each alias can expand only once!
import shlex
- args[:1] = shlex.split(alias,True)
+ args[:1] = shlex.split(alias,True)
command = args[0]
nargs = _Distribution._parse_command_opts(self, parser, args)
diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py
index 3345311a..5392e59f 100644
--- a/setuptools/tests/test_resources.py
+++ b/setuptools/tests/test_resources.py
@@ -185,7 +185,7 @@ class DistroTests(TestCase):
d,"Twisted>=1.5 fcgiapp>=0.1 ZConfig>=2.0 docutils>=0.3".split(),
["fastcgi", "docgen"]
)
- self.assertRaises(InvalidOption, d.requires, ["foo"])
+ self.assertRaises(UnknownExtra, d.requires, ["foo"])
@@ -203,6 +203,88 @@ class DistroTests(TestCase):
+class EntryPointTests(TestCase):
+
+ def assertfields(self, ep):
+ self.assertEqual(ep.name,"foo")
+ self.assertEqual(ep.module_name,"setuptools.tests.test_resources")
+ self.assertEqual(ep.attrs, ("EntryPointTests",))
+ self.assertEqual(ep.extras, ("x",))
+ self.failUnless(ep.load() is EntryPointTests)
+ self.assertEqual(
+ str(ep),
+ "foo = setuptools.tests.test_resources:EntryPointTests [x]"
+ )
+
+ def testBasics(self):
+ ep = EntryPoint(
+ "foo", "setuptools.tests.test_resources", ["EntryPointTests"],
+ ["x"]
+ )
+ self.assertfields(ep)
+
+ def testParse(self):
+ s = "foo = setuptools.tests.test_resources:EntryPointTests [x]"
+ ep = EntryPoint.parse(s)
+ self.assertfields(ep)
+
+ ep = EntryPoint.parse("bar baz= spammity[PING]")
+ self.assertEqual(ep.name,"bar baz")
+ self.assertEqual(ep.module_name,"spammity")
+ self.assertEqual(ep.attrs, ())
+ self.assertEqual(ep.extras, ("ping",))
+
+ ep = EntryPoint.parse(" fizzly = wocka:foo")
+ self.assertEqual(ep.name,"fizzly")
+ self.assertEqual(ep.module_name,"wocka")
+ self.assertEqual(ep.attrs, ("foo",))
+ self.assertEqual(ep.extras, ())
+
+
+
+
+
+ def testRejects(self):
+ for ep in [
+ "foo", "x=1=2", "x=a:b:c", "q=x/na", "fez=pish:tush-z", "x=f[a]>2",
+ ]:
+ try: EntryPoint.parse(ep)
+ except ValueError: pass
+ else: raise AssertionError("Should've been bad", ep)
+
+ def checkSubMap(self, m):
+ self.assertEqual(str(m),
+ "{"
+ "'feature2': EntryPoint.parse("
+ "'feature2 = another.module:SomeClass [extra1,extra2]'), "
+ "'feature1': EntryPoint.parse("
+ "'feature1 = somemodule:somefunction')"
+ "}"
+ )
+
+ submap_str = """
+ # define features for blah blah
+ feature1 = somemodule:somefunction
+ feature2 = another.module:SomeClass [extra1,extra2]
+ """
+
+ def testParseList(self):
+ self.checkSubMap(EntryPoint.parse_list("xyz", self.submap_str))
+ self.assertRaises(ValueError, EntryPoint.parse_list, "x a", "foo=bar")
+ self.assertRaises(ValueError, EntryPoint.parse_list, "x",
+ ["foo=baz", "foo=bar"])
+
+ def testParseMap(self):
+ m = EntryPoint.parse_map({'xyz':self.submap_str})
+ self.checkSubMap(m['xyz'])
+ self.assertEqual(m.keys(),['xyz'])
+ m = EntryPoint.parse_map("[xyz]\n"+self.submap_str)
+ self.checkSubMap(m['xyz'])
+ self.assertEqual(m.keys(),['xyz'])
+ self.assertRaises(ValueError, EntryPoint.parse_map, ["[xyz]", "[xyz]"])
+ self.assertRaises(ValueError, EntryPoint.parse_map, self.submap_str)
+
+
class RequirementsTests(TestCase):
def testBasics(self):