diff -r 82136b377981 -r e2d838bc1cfc Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst Thu Jun 09 12:31:51 2011 -0400 +++ b/Doc/packaging/setupcfg.rst Thu Jun 09 12:45:46 2011 -0400 @@ -156,7 +156,7 @@ commands - Defined Packaging command. A command is defined by its fully + Defines a Packaging command. A command is defined by its fully qualified name. *optional*, *multi* Examples:: @@ -167,7 +167,7 @@ package.setup.BdistDeb compilers - Defined Packaging compiler. A compiler is defined by its fully + Defines a Packaging compiler. A compiler is defined by its fully qualified name. *optional*, *multi* Example:: @@ -176,15 +176,17 @@ compilers = hotcompiler.SmartCCompiler -setup_hook - defines a callable that will be called right after the +setup_hooks + Defines a callable that will be called right after the :file:`setup.cfg` file is read. The callable receives the configuration - in form of a mapping and can make some changes to it. *optional* + in form of a mapping and can make some changes to it. Multiple values will + be called in the order specified. + *optional*, *multi* Example:: [global] - setup_hook = package.setup.customize_dist + setup_hooks = package.setup.customize_dist Metadata diff -r 82136b377981 -r e2d838bc1cfc Lib/packaging/config.py --- a/Lib/packaging/config.py Thu Jun 09 12:31:51 2011 -0400 +++ b/Lib/packaging/config.py Thu Jun 09 12:45:46 2011 -0400 @@ -65,13 +65,15 @@ """ def __init__(self, dist): self.dist = dist - self.setup_hook = None + self.setup_hooks = None - def run_hook(self, config): - if self.setup_hook is None: + def run_hooks(self, config): + if self.setup_hooks is None: return + # the hook gets only the config - self.setup_hook(config) + for hook in self.setup_hooks: + hook(config) def find_config_files(self): """Find as many configuration files as should be processed for this @@ -131,17 +133,23 @@ for section in parser.sections(): content[section] = dict(parser.items(section)) - # global:setup_hook is called *first* + # global:setup_hooks is called *first* if 'global' in content: - if 'setup_hook' in content['global']: - setup_hook = content['global']['setup_hook'] + if 'setup_hooks' in content['global']: + setup_hooks = content['global']['setup_hooks'] + setup_hooks = split_multiline(setup_hooks) + + if setup_hooks: + self.setup_hooks = [] + try: - self.setup_hook = resolve_name(setup_hook) + for hook in setup_hooks: + self.setup_hooks.append(resolve_name(hook)) except ImportError as e: logger.warning('could not import setup_hook: %s', e.args[0]) else: - self.run_hook(content) + self.run_hooks(content) metadata = self.dist.metadata diff -r 82136b377981 -r e2d838bc1cfc Lib/packaging/tests/test_config.py --- a/Lib/packaging/tests/test_config.py Thu Jun 09 12:31:51 2011 -0400 +++ b/Lib/packaging/tests/test_config.py Thu Jun 09 12:45:46 2011 -0400 @@ -90,7 +90,7 @@ compilers = packaging.tests.test_config.DCompiler -setup_hook = %(setup-hook)s +setup_hooks = %(setup-hooks)s @@ -186,7 +186,7 @@ def write_setup(self, kwargs=None): opts = {'description-file': 'README', 'extra-files': '', - 'setup-hook': 'packaging.tests.test_config.hook'} + 'setup-hooks': 'packaging.tests.test_config.hook'} if kwargs: opts.update(kwargs) self.write_file('setup.cfg', SETUP_CFG % opts, encoding='utf-8') @@ -319,13 +319,23 @@ self.assertEqual(ext.language, 'cxx') def test_missing_setuphook_warns(self): - self.write_setup({'setup-hook': 'this.does._not.exist'}) + self.write_setup({'setup-hooks': 'this.does._not.exist'}) self.write_file('README', 'yeah') dist = self.get_dist() logs = self.get_logs(logging.WARNING) self.assertEqual(1, len(logs)) self.assertIn('could not import setup_hook', logs[0]) + def test_multiple_setuphooks(self): + self.write_setup({ + 'setup-hooks': 'packaging.tests.test_config.hook\n' + ' packaging.tests.test_config.hook' + }) + self.write_file('README', 'yeah') + dist = self.get_dist() + # The hook should have run twice, appending .dev1 to the version twice + self.assertEqual(dist.metadata['Version'], '0.6.4.dev1.dev1') + def test_metadata_requires_description_files_missing(self): self.write_setup({'description-file': 'README\n README2'}) self.write_file('README', 'yeah') diff -r 82136b377981 -r e2d838bc1cfc Lib/packaging/tests/test_util.py --- a/Lib/packaging/tests/test_util.py Thu Jun 09 12:31:51 2011 -0400 +++ b/Lib/packaging/tests/test_util.py Thu Jun 09 12:45:46 2011 -0400 @@ -500,7 +500,7 @@ def test_cfg_to_args(self): opts = {'description-file': 'README', 'extra-files': '', - 'setup-hook': 'packaging.tests.test_config.hook'} + 'setup-hooks': 'packaging.tests.test_config.hook'} self.write_file('setup.cfg', SETUP_CFG % opts) self.write_file('README', 'loooong description')