mirror of https://github.com/python/cpython.git
Allow multiple values for package_data in setup.cfg (#11805).
Even though the resources system obsoletes data_files and package_data (see bug discussion), package_data still exists to allow compatibility with distutils and thus an easier transition. In setup.py, the values are lists of glob patterns, so the setup.cfg syntax needed a way to express multiple values too. Doc for this option will be added later as part of the big packaging doc patches. For now, the test serves as example. Reported by Erik Bray.
This commit is contained in:
parent
591f6e82bd
commit
31aefde876
|
@ -20,7 +20,6 @@ def _check_name(name, packages):
|
||||||
if '.' not in name:
|
if '.' not in name:
|
||||||
return
|
return
|
||||||
parts = name.split('.')
|
parts = name.split('.')
|
||||||
modname = parts[-1]
|
|
||||||
parent = '.'.join(parts[:-1])
|
parent = '.'.join(parts[:-1])
|
||||||
if parent not in packages:
|
if parent not in packages:
|
||||||
# we could log a warning instead of raising, but what's the use
|
# we could log a warning instead of raising, but what's the use
|
||||||
|
@ -227,13 +226,25 @@ def _read_setup_cfg(self, parser, cfg_filename):
|
||||||
self.dist.scripts = [self.dist.scripts]
|
self.dist.scripts = [self.dist.scripts]
|
||||||
|
|
||||||
self.dist.package_data = {}
|
self.dist.package_data = {}
|
||||||
|
# bookkeeping for the loop below
|
||||||
|
firstline = True
|
||||||
|
prev = None
|
||||||
|
|
||||||
for line in files.get('package_data', []):
|
for line in files.get('package_data', []):
|
||||||
data = line.split('=')
|
if '=' in line:
|
||||||
if len(data) != 2:
|
# package name -- file globs or specs
|
||||||
raise ValueError('invalid line for package_data: %s '
|
key, value = line.split('=')
|
||||||
'(misses "=")' % line)
|
prev = self.dist.package_data[key.strip()] = value.split()
|
||||||
key, value = data
|
elif firstline:
|
||||||
self.dist.package_data[key.strip()] = value.strip()
|
# invalid continuation on the first line
|
||||||
|
raise PackagingOptionError(
|
||||||
|
'malformed package_data first line: %r (misses "=")' %
|
||||||
|
line)
|
||||||
|
else:
|
||||||
|
# continuation, add to last seen package name
|
||||||
|
prev.extend(line.split())
|
||||||
|
|
||||||
|
firstline = False
|
||||||
|
|
||||||
self.dist.data_files = []
|
self.dist.data_files = []
|
||||||
for data in files.get('data_files', []):
|
for data in files.get('data_files', []):
|
||||||
|
|
|
@ -66,11 +66,15 @@
|
||||||
bin/taunt
|
bin/taunt
|
||||||
|
|
||||||
package_data =
|
package_data =
|
||||||
cheese = data/templates/*
|
cheese = data/templates/* doc/*
|
||||||
|
doc/images/*.png
|
||||||
|
|
||||||
|
|
||||||
extra_files = %(extra-files)s
|
extra_files = %(extra-files)s
|
||||||
|
|
||||||
# Replaces MANIFEST.in
|
# Replaces MANIFEST.in
|
||||||
|
# FIXME no, it's extra_files
|
||||||
|
# (but sdist_extra is a better name, should use it)
|
||||||
sdist_extra =
|
sdist_extra =
|
||||||
include THANKS HACKING
|
include THANKS HACKING
|
||||||
recursive-include examples *.txt *.py
|
recursive-include examples *.txt *.py
|
||||||
|
@ -96,6 +100,17 @@
|
||||||
sub_commands = foo
|
sub_commands = foo
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
SETUP_CFG_PKGDATA_BUGGY_1 = """
|
||||||
|
[files]
|
||||||
|
package_data = foo.*
|
||||||
|
"""
|
||||||
|
|
||||||
|
SETUP_CFG_PKGDATA_BUGGY_2 = """
|
||||||
|
[files]
|
||||||
|
package_data =
|
||||||
|
foo.*
|
||||||
|
"""
|
||||||
|
|
||||||
# Can not be merged with SETUP_CFG else install_dist
|
# Can not be merged with SETUP_CFG else install_dist
|
||||||
# command will fail when trying to compile C sources
|
# command will fail when trying to compile C sources
|
||||||
# TODO use a DummyCommand to mock build_ext
|
# TODO use a DummyCommand to mock build_ext
|
||||||
|
@ -276,13 +291,14 @@ def test_config(self):
|
||||||
|
|
||||||
self.assertEqual(dist.packages, ['one', 'two', 'three'])
|
self.assertEqual(dist.packages, ['one', 'two', 'three'])
|
||||||
self.assertEqual(dist.py_modules, ['haven'])
|
self.assertEqual(dist.py_modules, ['haven'])
|
||||||
self.assertEqual(dist.package_data, {'cheese': 'data/templates/*'})
|
self.assertEqual(dist.package_data,
|
||||||
self.assertEqual(
|
{'cheese': ['data/templates/*', 'doc/*',
|
||||||
|
'doc/images/*.png']})
|
||||||
|
self.assertEqual(dist.data_files,
|
||||||
{'bm/b1.gif': '{icon}/b1.gif',
|
{'bm/b1.gif': '{icon}/b1.gif',
|
||||||
'bm/b2.gif': '{icon}/b2.gif',
|
'bm/b2.gif': '{icon}/b2.gif',
|
||||||
'Cfg/data.CFG': '{config}/baBar/data.CFG',
|
'Cfg/data.CFG': '{config}/baBar/data.CFG',
|
||||||
'init_script': '{script}/JunGle/init_script'},
|
'init_script': '{script}/JunGle/init_script'})
|
||||||
dist.data_files)
|
|
||||||
|
|
||||||
self.assertEqual(dist.package_dir, 'src')
|
self.assertEqual(dist.package_dir, 'src')
|
||||||
|
|
||||||
|
@ -293,8 +309,8 @@ def test_config(self):
|
||||||
# this file would be __main__.Foo when run as "python test_config.py".
|
# this file would be __main__.Foo when run as "python test_config.py".
|
||||||
# The name FooBarBazTest should be unique enough to prevent
|
# The name FooBarBazTest should be unique enough to prevent
|
||||||
# collisions.
|
# collisions.
|
||||||
self.assertEqual('FooBarBazTest',
|
self.assertEqual(dist.get_command_obj('foo').__class__.__name__,
|
||||||
dist.get_command_obj('foo').__class__.__name__)
|
'FooBarBazTest')
|
||||||
|
|
||||||
# did the README got loaded ?
|
# did the README got loaded ?
|
||||||
self.assertEqual(dist.metadata['description'], 'yeah')
|
self.assertEqual(dist.metadata['description'], 'yeah')
|
||||||
|
@ -304,6 +320,13 @@ def test_config(self):
|
||||||
d = new_compiler(compiler='d')
|
d = new_compiler(compiler='d')
|
||||||
self.assertEqual(d.description, 'D Compiler')
|
self.assertEqual(d.description, 'D Compiler')
|
||||||
|
|
||||||
|
# check error reporting for invalid package_data value
|
||||||
|
self.write_file('setup.cfg', SETUP_CFG_PKGDATA_BUGGY_1)
|
||||||
|
self.assertRaises(PackagingOptionError, self.get_dist)
|
||||||
|
|
||||||
|
self.write_file('setup.cfg', SETUP_CFG_PKGDATA_BUGGY_2)
|
||||||
|
self.assertRaises(PackagingOptionError, self.get_dist)
|
||||||
|
|
||||||
def test_multiple_description_file(self):
|
def test_multiple_description_file(self):
|
||||||
self.write_setup({'description-file': 'README CHANGES'})
|
self.write_setup({'description-file': 'README CHANGES'})
|
||||||
self.write_file('README', 'yeah')
|
self.write_file('README', 'yeah')
|
||||||
|
|
|
@ -466,6 +466,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #11805: package_data in setup.cfg should allow more than one value.
|
||||||
|
|
||||||
- Issue #13901: Prevent test_distutils failures on OS X with --enable-shared.
|
- Issue #13901: Prevent test_distutils failures on OS X with --enable-shared.
|
||||||
|
|
||||||
- Issue #13676: Handle strings with embedded zeros correctly in sqlite3.
|
- Issue #13676: Handle strings with embedded zeros correctly in sqlite3.
|
||||||
|
|
Loading…
Reference in New Issue