diff options
Diffstat (limited to 'setuptools')
| -rw-r--r-- | setuptools/command/__init__.py | 13 | ||||
| -rwxr-xr-x | setuptools/command/egg_info.py | 38 | ||||
| -rw-r--r-- | setuptools/dist.py | 69 | ||||
| -rw-r--r-- | setuptools/tests/test_resources.py | 84 |
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): |
