Minor improvement to extensions in setup.cfg: check parent package
This commit is contained in:
parent
336b4e4ff3
commit
d9299e97ab
|
@ -769,7 +769,9 @@ needs to have its options defined in a dedicated section. Here's an example::
|
|||
|
||||
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
|
||||
|
|
|
@ -16,6 +16,19 @@ from packaging.command import set_command
|
|||
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 @@ class Config:
|
|||
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 @@ class Config:
|
|||
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'),
|
||||
|
|
|
@ -105,6 +105,7 @@ EXT_SETUP_CFG = """
|
|||
[files]
|
||||
packages = one
|
||||
two
|
||||
parent.undeclared
|
||||
|
||||
[extension:one.speed_coconuts]
|
||||
sources = c_src/speed_coconuts.c
|
||||
|
@ -122,6 +123,11 @@ extra_compile_args = -fPIC -O2
|
|||
-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 @@ EXT_SETUP_CFG_BUGGY_1 = """
|
|||
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 @@ class ConfigTestCase(support.TempdirManager,
|
|||
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 @@ class ConfigTestCase(support.TempdirManager,
|
|||
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 @@ class ConfigTestCase(support.TempdirManager,
|
|||
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()
|
||||
|
|
Loading…
Reference in New Issue