Mercurial > cpython-lru_cache-weakref
changeset 72181:c1949bde461e
Minor improvement to extensions in setup.cfg: check parent package
| author | Éric Araujo <merwok@netwok.org> |
|---|---|
| date | Thu, 01 Sep 2011 07:01:13 +0200 |
| parents | 0cdd174d1bc4 |
| children | b166dc85f604 |
| files | Doc/packaging/setupcfg.rst Lib/packaging/config.py Lib/packaging/tests/test_config.py |
| diffstat | 3 files changed, 50 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/Doc/packaging/setupcfg.rst Thu Sep 01 06:29:11 2011 +0200 +++ b/Doc/packaging/setupcfg.rst Thu Sep 01 07:01:13 2011 +0200 @@ -769,7 +769,9 @@ The section name must start with ``extension:``; the right-hand part is used as the full name (including a parent package, if any) of the extension. Whitespace -around the extension name is allowed. +around the extension name is allowed. If the extension module is not standalone +(e.g. ``_bisect``) but part of a package (e.g. ``thing._speedups``), the parent +package must be listed in the ``packages`` field. Valid fields and their values are listed in the documentation of the :class:`packaging.compiler.extension.Extension` class; values documented as Python lists translate to multi-line values in the configuration file. In
--- a/Lib/packaging/config.py Thu Sep 01 06:29:11 2011 +0200 +++ b/Lib/packaging/config.py Thu Sep 01 07:01:13 2011 +0200 @@ -16,6 +16,19 @@ from packaging.markers import interpret +def _check_name(name, packages): + if '.' not in name: + return + parts = name.split('.') + modname = parts[-1] + parent = '.'.join(parts[:-1]) + if parent not in packages: + # we could log a warning instead of raising, but what's the use + # of letting people build modules they can't import? + raise PackagingOptionError( + 'parent package for extension %r not found' % name) + + def _pop_values(values_dct, key): """Remove values from the dictionary and convert them as a list""" vals_str = values_dct.pop(key, '') @@ -142,7 +155,8 @@ try: hook = resolve_name(line) except ImportError as e: - logger.warning('cannot find setup hook: %s', e.args[0]) + logger.warning('cannot find setup hook: %s', + e.args[0]) else: self.setup_hooks.append(hook) self.run_hooks(content) @@ -259,8 +273,10 @@ raise PackagingOptionError( 'extension name should be given as [extension: name], ' 'not as key') + name = labels[1].strip() + _check_name(name, self.dist.packages) ext_modules.append(Extension( - labels[1].strip(), + name, _pop_values(values_dct, 'sources'), _pop_values(values_dct, 'include_dirs'), _pop_values(values_dct, 'define_macros'),
--- a/Lib/packaging/tests/test_config.py Thu Sep 01 06:29:11 2011 +0200 +++ b/Lib/packaging/tests/test_config.py Thu Sep 01 07:01:13 2011 +0200 @@ -105,6 +105,7 @@ [files] packages = one two + parent.undeclared [extension:one.speed_coconuts] sources = c_src/speed_coconuts.c @@ -122,6 +123,11 @@ -DGECODE_VERSION=$(./gecode_version) -- sys.platform != 'win32' /DGECODE_VERSION='win32' -- sys.platform == 'win32' language = cxx + +# corner case: if the parent package of an extension is declared but +# not its grandparent, it's legal +[extension: parent.undeclared._speed] +sources = parent/undeclared/_speed.c """ EXT_SETUP_CFG_BUGGY_1 = """ @@ -129,6 +135,21 @@ name = crash_here """ +EXT_SETUP_CFG_BUGGY_2 = """ +[files] +packages = ham + +[extension: spam.eggs] +""" + +EXT_SETUP_CFG_BUGGY_3 = """ +[files] +packages = ok + ok.works + +[extension: ok.works.breaks._ext] +""" + HOOKS_MODULE = """ import logging @@ -314,7 +335,7 @@ dist = self.get_dist() ext_modules = dict((mod.name, mod) for mod in dist.ext_modules) - self.assertEqual(len(ext_modules), 2) + self.assertEqual(len(ext_modules), 3) ext = ext_modules.get('one.speed_coconuts') self.assertEqual(ext.sources, ['c_src/speed_coconuts.c']) self.assertEqual(ext.define_macros, ['HAVE_CAIRO', 'HAVE_GTK2']) @@ -341,6 +362,12 @@ self.write_file('setup.cfg', EXT_SETUP_CFG_BUGGY_1) self.assertRaises(PackagingOptionError, self.get_dist) + self.write_file('setup.cfg', EXT_SETUP_CFG_BUGGY_2) + self.assertRaises(PackagingOptionError, self.get_dist) + + self.write_file('setup.cfg', EXT_SETUP_CFG_BUGGY_3) + self.assertRaises(PackagingOptionError, self.get_dist) + def test_project_setup_hook_works(self): # Bug #11637: ensure the project directory is on sys.path to allow # project-specific hooks @@ -364,7 +391,7 @@ self.write_setup({ 'setup-hooks': '\n packaging.tests.test_config.first_hook' '\n packaging.tests.test_config.missing_hook' - '\n packaging.tests.test_config.third_hook' + '\n packaging.tests.test_config.third_hook', }) self.write_file('README', 'yeah') dist = self.get_dist()
