mirror of
https://github.com/python/cpython.git
synced 2025-08-19 08:11:46 +00:00
Branch merge
This commit is contained in:
commit
04410c05c1
7 changed files with 99 additions and 47 deletions
|
@ -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 @@ class Config:
|
||||||
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', []):
|
||||||
|
|
|
@ -287,6 +287,7 @@ class MainProgram:
|
||||||
|
|
||||||
# optional string entries
|
# optional string entries
|
||||||
if 'keywords' in self.data and self.data['keywords']:
|
if 'keywords' in self.data and self.data['keywords']:
|
||||||
|
# XXX shoud use comma to separate, not space
|
||||||
fp.write('keywords = %s\n' % ' '.join(self.data['keywords']))
|
fp.write('keywords = %s\n' % ' '.join(self.data['keywords']))
|
||||||
for name in ('home_page', 'author', 'author_email',
|
for name in ('home_page', 'author', 'author_email',
|
||||||
'maintainer', 'maintainer_email', 'description-file'):
|
'maintainer', 'maintainer_email', 'description-file'):
|
||||||
|
@ -306,17 +307,29 @@ class MainProgram:
|
||||||
fp.write('%s = ' % name)
|
fp.write('%s = ' % name)
|
||||||
fp.write(''.join(' %s\n' % val
|
fp.write(''.join(' %s\n' % val
|
||||||
for val in self.data[name]).lstrip())
|
for val in self.data[name]).lstrip())
|
||||||
|
|
||||||
fp.write('\n[files]\n')
|
fp.write('\n[files]\n')
|
||||||
for name in ('packages', 'modules', 'scripts',
|
|
||||||
'package_data', 'extra_files'):
|
for name in ('packages', 'modules', 'scripts', 'extra_files'):
|
||||||
if not(name in self.data and self.data[name]):
|
if not(name in self.data and self.data[name]):
|
||||||
continue
|
continue
|
||||||
fp.write('%s = %s\n'
|
fp.write('%s = %s\n'
|
||||||
% (name, '\n '.join(self.data[name]).strip()))
|
% (name, '\n '.join(self.data[name]).strip()))
|
||||||
fp.write('\nresources =\n')
|
|
||||||
for src, dest in self.data['resources']:
|
if self.data.get('package_data'):
|
||||||
fp.write(' %s = %s\n' % (src, dest))
|
fp.write('package_data =\n')
|
||||||
fp.write('\n')
|
for pkg, spec in sorted(self.data['package_data'].items()):
|
||||||
|
# put one spec per line, indented under the package name
|
||||||
|
indent = ' ' * (len(pkg) + 7)
|
||||||
|
spec = ('\n' + indent).join(spec)
|
||||||
|
fp.write(' %s = %s\n' % (pkg, spec))
|
||||||
|
fp.write('\n')
|
||||||
|
|
||||||
|
if self.data.get('resources'):
|
||||||
|
fp.write('resources =\n')
|
||||||
|
for src, dest in self.data['resources']:
|
||||||
|
fp.write(' %s = %s\n' % (src, dest))
|
||||||
|
fp.write('\n')
|
||||||
|
|
||||||
os.chmod(_FILENAME, 0o644)
|
os.chmod(_FILENAME, 0o644)
|
||||||
logger.info('Wrote "%s".' % _FILENAME)
|
logger.info('Wrote "%s".' % _FILENAME)
|
||||||
|
@ -349,7 +362,6 @@ class MainProgram:
|
||||||
('long_description', 'description'),
|
('long_description', 'description'),
|
||||||
('url', 'home_page'),
|
('url', 'home_page'),
|
||||||
('platforms', 'platform'),
|
('platforms', 'platform'),
|
||||||
# backport only for 2.5+
|
|
||||||
('provides', 'provides-dist'),
|
('provides', 'provides-dist'),
|
||||||
('obsoletes', 'obsoletes-dist'),
|
('obsoletes', 'obsoletes-dist'),
|
||||||
('requires', 'requires-dist'))
|
('requires', 'requires-dist'))
|
||||||
|
@ -385,14 +397,8 @@ class MainProgram:
|
||||||
for src in srcs]
|
for src in srcs]
|
||||||
data['resources'].extend(files)
|
data['resources'].extend(files)
|
||||||
|
|
||||||
# 2.2 package_data -> extra_files
|
# 2.2 package_data
|
||||||
package_dirs = dist.package_dir or {}
|
data['package_data'] = dist.package_data.copy()
|
||||||
for package, extras in dist.package_data.items() or []:
|
|
||||||
package_dir = package_dirs.get(package, package)
|
|
||||||
for file_ in extras:
|
|
||||||
if package_dir:
|
|
||||||
file_ = package_dir + '/' + file_
|
|
||||||
data['extra_files'].append(file_)
|
|
||||||
|
|
||||||
# Use README file if its content is the desciption
|
# Use README file if its content is the desciption
|
||||||
if "description" in data:
|
if "description" in data:
|
||||||
|
|
|
@ -24,11 +24,17 @@ class BuildPyTestCase(support.TempdirManager,
|
||||||
f.write("# Pretend this is a package.")
|
f.write("# Pretend this is a package.")
|
||||||
finally:
|
finally:
|
||||||
f.close()
|
f.close()
|
||||||
|
# let's have two files to make sure globbing works
|
||||||
f = open(os.path.join(pkg_dir, "README.txt"), "w")
|
f = open(os.path.join(pkg_dir, "README.txt"), "w")
|
||||||
try:
|
try:
|
||||||
f.write("Info about this package")
|
f.write("Info about this package")
|
||||||
finally:
|
finally:
|
||||||
f.close()
|
f.close()
|
||||||
|
f = open(os.path.join(pkg_dir, "HACKING.txt"), "w")
|
||||||
|
try:
|
||||||
|
f.write("How to contribute")
|
||||||
|
finally:
|
||||||
|
f.close()
|
||||||
|
|
||||||
destination = self.mkdtemp()
|
destination = self.mkdtemp()
|
||||||
|
|
||||||
|
@ -42,7 +48,7 @@ class BuildPyTestCase(support.TempdirManager,
|
||||||
convert_2to3_doctests=None,
|
convert_2to3_doctests=None,
|
||||||
use_2to3=False)
|
use_2to3=False)
|
||||||
dist.packages = ["pkg"]
|
dist.packages = ["pkg"]
|
||||||
dist.package_data = {"pkg": ["README.txt"]}
|
dist.package_data = {"pkg": ["*.txt"]}
|
||||||
dist.package_dir = sources
|
dist.package_dir = sources
|
||||||
|
|
||||||
cmd = build_py(dist)
|
cmd = build_py(dist)
|
||||||
|
@ -55,15 +61,19 @@ class BuildPyTestCase(support.TempdirManager,
|
||||||
# This makes sure the list of outputs includes byte-compiled
|
# This makes sure the list of outputs includes byte-compiled
|
||||||
# files for Python modules but not for package data files
|
# files for Python modules but not for package data files
|
||||||
# (there shouldn't *be* byte-code files for those!).
|
# (there shouldn't *be* byte-code files for those!).
|
||||||
#
|
# FIXME the test below is not doing what the comment above says, and
|
||||||
self.assertEqual(len(cmd.get_outputs()), 3)
|
# if it did it would show a code bug: if we add a demo.py file to
|
||||||
|
# package_data, it gets byte-compiled!
|
||||||
|
outputs = cmd.get_outputs()
|
||||||
|
self.assertEqual(len(outputs), 4, outputs)
|
||||||
pkgdest = os.path.join(destination, "pkg")
|
pkgdest = os.path.join(destination, "pkg")
|
||||||
files = os.listdir(pkgdest)
|
files = os.listdir(pkgdest)
|
||||||
pycache_dir = os.path.join(pkgdest, "__pycache__")
|
pycache_dir = os.path.join(pkgdest, "__pycache__")
|
||||||
self.assertIn("__init__.py", files)
|
self.assertIn("__init__.py", files)
|
||||||
self.assertIn("README.txt", files)
|
self.assertIn("README.txt", files)
|
||||||
|
self.assertIn("HACKING.txt", files)
|
||||||
pyc_files = os.listdir(pycache_dir)
|
pyc_files = os.listdir(pycache_dir)
|
||||||
self.assertIn("__init__.%s.pyc" % imp.get_tag(), pyc_files)
|
self.assertEqual(["__init__.%s.pyc" % imp.get_tag()], pyc_files)
|
||||||
|
|
||||||
def test_empty_package_dir(self):
|
def test_empty_package_dir(self):
|
||||||
# See SF 1668596/1720897.
|
# See SF 1668596/1720897.
|
||||||
|
|
|
@ -73,7 +73,6 @@ class SDistTestCase(support.TempdirManager,
|
||||||
'author_email': 'xxx'}
|
'author_email': 'xxx'}
|
||||||
dist = Distribution(metadata)
|
dist = Distribution(metadata)
|
||||||
dist.packages = ['somecode']
|
dist.packages = ['somecode']
|
||||||
dist.include_package_data = True
|
|
||||||
cmd = sdist(dist)
|
cmd = sdist(dist)
|
||||||
cmd.dist_dir = 'dist'
|
cmd.dist_dir = 'dist'
|
||||||
return dist, cmd
|
return dist, cmd
|
||||||
|
|
|
@ -66,11 +66,15 @@ scripts =
|
||||||
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 @@ setup_hooks = %(setup-hooks)s
|
||||||
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 @@ class ConfigTestCase(support.TempdirManager,
|
||||||
|
|
||||||
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 @@ class ConfigTestCase(support.TempdirManager,
|
||||||
# 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 @@ class ConfigTestCase(support.TempdirManager,
|
||||||
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')
|
||||||
|
|
|
@ -116,7 +116,6 @@ class CreateTestCase(support.TempdirManager,
|
||||||
package_data={
|
package_data={
|
||||||
'babar': ['Pom', 'Flora', 'Alexander'],
|
'babar': ['Pom', 'Flora', 'Alexander'],
|
||||||
'me': ['dady', 'mumy', 'sys', 'bro'],
|
'me': ['dady', 'mumy', 'sys', 'bro'],
|
||||||
'': ['setup.py', 'README'],
|
|
||||||
'pyxfoil': ['fengine.so'],
|
'pyxfoil': ['fengine.so'],
|
||||||
},
|
},
|
||||||
scripts=['my_script', 'bin/run'],
|
scripts=['my_script', 'bin/run'],
|
||||||
|
@ -150,16 +149,15 @@ class CreateTestCase(support.TempdirManager,
|
||||||
mymodule
|
mymodule
|
||||||
scripts = my_script
|
scripts = my_script
|
||||||
bin/run
|
bin/run
|
||||||
extra_files = Martinique/Lamentin/dady
|
package_data =
|
||||||
Martinique/Lamentin/mumy
|
babar = Pom
|
||||||
Martinique/Lamentin/sys
|
Flora
|
||||||
Martinique/Lamentin/bro
|
Alexander
|
||||||
setup.py
|
me = dady
|
||||||
README
|
mumy
|
||||||
Pom
|
sys
|
||||||
Flora
|
bro
|
||||||
Alexander
|
pyxfoil = fengine.so
|
||||||
pyxfoil/fengine.so
|
|
||||||
|
|
||||||
resources =
|
resources =
|
||||||
README.rst = {doc}
|
README.rst = {doc}
|
||||||
|
@ -217,8 +215,9 @@ ho, baby!
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
packages = pyxfoil
|
packages = pyxfoil
|
||||||
extra_files = pyxfoil/fengine.so
|
package_data =
|
||||||
pyxfoil/babar.so
|
pyxfoil = fengine.so
|
||||||
|
babar.so
|
||||||
|
|
||||||
resources =
|
resources =
|
||||||
README.rst = {doc}
|
README.rst = {doc}
|
||||||
|
|
|
@ -466,6 +466,10 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #13712: pysetup create should not convert package_data to extra_files.
|
||||||
|
|
||||||
|
- Issue #11805: package_data in setup.cfg should allow more than one value.
|
||||||
|
|
||||||
- Issue #13933: IDLE auto-complete did not work with some imported
|
- Issue #13933: IDLE auto-complete did not work with some imported
|
||||||
module, like hashlib. (Patch by Roger Serwy)
|
module, like hashlib. (Patch by Roger Serwy)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue