From 591f6e82bd24361b7628bcb47830e18efb354db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sat, 4 Feb 2012 21:43:07 +0100 Subject: Improve one packaging test, remove a setuptoolism in another --- Lib/packaging/tests/test_command_build_py.py | 18 ++++++++++++++---- Lib/packaging/tests/test_command_sdist.py | 1 - 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Lib/packaging/tests/test_command_build_py.py b/Lib/packaging/tests/test_command_build_py.py index f7f26da..0599bf2 100644 --- a/Lib/packaging/tests/test_command_build_py.py +++ b/Lib/packaging/tests/test_command_build_py.py @@ -24,11 +24,17 @@ class BuildPyTestCase(support.TempdirManager, f.write("# Pretend this is a package.") finally: f.close() + # let's have two files to make sure globbing works f = open(os.path.join(pkg_dir, "README.txt"), "w") try: f.write("Info about this package") finally: f.close() + f = open(os.path.join(pkg_dir, "HACKING.txt"), "w") + try: + f.write("How to contribute") + finally: + f.close() destination = self.mkdtemp() @@ -42,7 +48,7 @@ class BuildPyTestCase(support.TempdirManager, convert_2to3_doctests=None, use_2to3=False) dist.packages = ["pkg"] - dist.package_data = {"pkg": ["README.txt"]} + dist.package_data = {"pkg": ["*.txt"]} dist.package_dir = sources cmd = build_py(dist) @@ -55,15 +61,19 @@ class BuildPyTestCase(support.TempdirManager, # This makes sure the list of outputs includes byte-compiled # files for Python modules but not for package data files # (there shouldn't *be* byte-code files for those!). - # - self.assertEqual(len(cmd.get_outputs()), 3) + # FIXME the test below is not doing what the comment above says, and + # 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") files = os.listdir(pkgdest) pycache_dir = os.path.join(pkgdest, "__pycache__") self.assertIn("__init__.py", files) self.assertIn("README.txt", files) + self.assertIn("HACKING.txt", files) 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): # See SF 1668596/1720897. diff --git a/Lib/packaging/tests/test_command_sdist.py b/Lib/packaging/tests/test_command_sdist.py index 47c455e..d974718 100644 --- a/Lib/packaging/tests/test_command_sdist.py +++ b/Lib/packaging/tests/test_command_sdist.py @@ -73,7 +73,6 @@ class SDistTestCase(support.TempdirManager, 'author_email': 'xxx'} dist = Distribution(metadata) dist.packages = ['somecode'] - dist.include_package_data = True cmd = sdist(dist) cmd.dist_dir = 'dist' return dist, cmd -- cgit v0.12 From 31aefde8760c3d407ffe8dc044e5ae8f5daeb12c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sat, 4 Feb 2012 21:53:07 +0100 Subject: 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. --- Lib/packaging/config.py | 25 ++++++++++++++++++------- Lib/packaging/tests/test_config.py | 37 ++++++++++++++++++++++++++++++------- Misc/NEWS | 2 ++ 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/Lib/packaging/config.py b/Lib/packaging/config.py index 366faea..ab026a8 100644 --- a/Lib/packaging/config.py +++ b/Lib/packaging/config.py @@ -20,7 +20,6 @@ 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 @@ -227,13 +226,25 @@ class Config: self.dist.scripts = [self.dist.scripts] self.dist.package_data = {} + # bookkeeping for the loop below + firstline = True + prev = None + for line in files.get('package_data', []): - data = line.split('=') - if len(data) != 2: - raise ValueError('invalid line for package_data: %s ' - '(misses "=")' % line) - key, value = data - self.dist.package_data[key.strip()] = value.strip() + if '=' in line: + # package name -- file globs or specs + key, value = line.split('=') + prev = self.dist.package_data[key.strip()] = value.split() + elif firstline: + # 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 = [] for data in files.get('data_files', []): diff --git a/Lib/packaging/tests/test_config.py b/Lib/packaging/tests/test_config.py index 613d493..0d76b29 100644 --- a/Lib/packaging/tests/test_config.py +++ b/Lib/packaging/tests/test_config.py @@ -66,11 +66,15 @@ scripts = bin/taunt package_data = - cheese = data/templates/* + cheese = data/templates/* doc/* + doc/images/*.png + extra_files = %(extra-files)s # Replaces MANIFEST.in +# FIXME no, it's extra_files +# (but sdist_extra is a better name, should use it) sdist_extra = include THANKS HACKING recursive-include examples *.txt *.py @@ -96,6 +100,17 @@ setup_hooks = %(setup-hooks)s 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 # command will fail when trying to compile C sources # 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.py_modules, ['haven']) - self.assertEqual(dist.package_data, {'cheese': 'data/templates/*'}) - self.assertEqual( + self.assertEqual(dist.package_data, + {'cheese': ['data/templates/*', 'doc/*', + 'doc/images/*.png']}) + self.assertEqual(dist.data_files, {'bm/b1.gif': '{icon}/b1.gif', 'bm/b2.gif': '{icon}/b2.gif', 'Cfg/data.CFG': '{config}/baBar/data.CFG', - 'init_script': '{script}/JunGle/init_script'}, - dist.data_files) + 'init_script': '{script}/JunGle/init_script'}) 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". # The name FooBarBazTest should be unique enough to prevent # collisions. - self.assertEqual('FooBarBazTest', - dist.get_command_obj('foo').__class__.__name__) + self.assertEqual(dist.get_command_obj('foo').__class__.__name__, + 'FooBarBazTest') # did the README got loaded ? self.assertEqual(dist.metadata['description'], 'yeah') @@ -304,6 +320,13 @@ class ConfigTestCase(support.TempdirManager, d = new_compiler(compiler='d') 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): self.write_setup({'description-file': 'README CHANGES'}) self.write_file('README', 'yeah') diff --git a/Misc/NEWS b/Misc/NEWS index 72a943d..91972bf 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -466,6 +466,8 @@ Core and Builtins 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 #13676: Handle strings with embedded zeros correctly in sqlite3. -- cgit v0.12 From dcfcb6458206a7cf6e61e8f91f756e62137125fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Sun, 5 Feb 2012 10:26:16 +0100 Subject: Stop converting package_data to extra_files in pysetup create (#13712). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pysetup create, the setup.cfg creation helper, used to convert package_data (from an existing setup.py) into extra_files, the replacement for MANIFEST.in, but these files are only present in sdists, not installed: they don’t have the same use case at all, so converting one into the other did not work. --- Lib/packaging/create.py | 36 +++++++++++++++++++++--------------- Lib/packaging/tests/test_create.py | 25 ++++++++++++------------- Misc/NEWS | 2 ++ 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/Lib/packaging/create.py b/Lib/packaging/create.py index 5abe47b..3d45ca9 100644 --- a/Lib/packaging/create.py +++ b/Lib/packaging/create.py @@ -287,6 +287,7 @@ class MainProgram: # optional string entries 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'])) for name in ('home_page', 'author', 'author_email', 'maintainer', 'maintainer_email', 'description-file'): @@ -306,17 +307,29 @@ class MainProgram: fp.write('%s = ' % name) fp.write(''.join(' %s\n' % val for val in self.data[name]).lstrip()) + 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]): continue fp.write('%s = %s\n' % (name, '\n '.join(self.data[name]).strip())) - fp.write('\nresources =\n') - for src, dest in self.data['resources']: - fp.write(' %s = %s\n' % (src, dest)) - fp.write('\n') + + if self.data.get('package_data'): + fp.write('package_data =\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) logger.info('Wrote "%s".' % _FILENAME) @@ -349,7 +362,6 @@ class MainProgram: ('long_description', 'description'), ('url', 'home_page'), ('platforms', 'platform'), - # backport only for 2.5+ ('provides', 'provides-dist'), ('obsoletes', 'obsoletes-dist'), ('requires', 'requires-dist')) @@ -385,14 +397,8 @@ class MainProgram: for src in srcs] data['resources'].extend(files) - # 2.2 package_data -> extra_files - package_dirs = dist.package_dir or {} - 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_) + # 2.2 package_data + data['package_data'] = dist.package_data.copy() # Use README file if its content is the desciption if "description" in data: diff --git a/Lib/packaging/tests/test_create.py b/Lib/packaging/tests/test_create.py index 07824b1..76bc331 100644 --- a/Lib/packaging/tests/test_create.py +++ b/Lib/packaging/tests/test_create.py @@ -116,7 +116,6 @@ class CreateTestCase(support.TempdirManager, package_data={ 'babar': ['Pom', 'Flora', 'Alexander'], 'me': ['dady', 'mumy', 'sys', 'bro'], - '': ['setup.py', 'README'], 'pyxfoil': ['fengine.so'], }, scripts=['my_script', 'bin/run'], @@ -150,16 +149,15 @@ class CreateTestCase(support.TempdirManager, mymodule scripts = my_script bin/run - extra_files = Martinique/Lamentin/dady - Martinique/Lamentin/mumy - Martinique/Lamentin/sys - Martinique/Lamentin/bro - setup.py - README - Pom - Flora - Alexander - pyxfoil/fengine.so + package_data = + babar = Pom + Flora + Alexander + me = dady + mumy + sys + bro + pyxfoil = fengine.so resources = README.rst = {doc} @@ -217,8 +215,9 @@ ho, baby! [files] packages = pyxfoil - extra_files = pyxfoil/fengine.so - pyxfoil/babar.so + package_data = + pyxfoil = fengine.so + babar.so resources = README.rst = {doc} diff --git a/Misc/NEWS b/Misc/NEWS index 91972bf..41fc63e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -466,6 +466,8 @@ Core and Builtins 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 #13901: Prevent test_distutils failures on OS X with --enable-shared. -- cgit v0.12