[Python-checkins] cpython (merge default -> default): Branch merge

eric.araujo python-checkins at python.org
Sun Feb 5 10:49:23 CET 2012


http://hg.python.org/cpython/rev/028e2ba85685
changeset:   74782:028e2ba85685
parent:      74778:ca8c2a185aa3
parent:      74781:edb6f9fb54ac
user:        Éric Araujo <merwok at netwok.org>
date:        Sun Feb 05 10:48:52 2012 +0100
summary:
  Branch merge

files:
  Lib/packaging/config.py                      |  25 ++++-
  Lib/packaging/create.py                      |  36 +++++----
  Lib/packaging/tests/test_command_build_py.py |  18 +++-
  Lib/packaging/tests/test_command_sdist.py    |   1 -
  Lib/packaging/tests/test_config.py           |  37 ++++++++-
  Lib/packaging/tests/test_create.py           |  25 +++---
  Misc/NEWS                                    |   4 +
  7 files changed, 99 insertions(+), 47 deletions(-)


diff --git a/Lib/packaging/config.py b/Lib/packaging/config.py
--- a/Lib/packaging/config.py
+++ b/Lib/packaging/config.py
@@ -20,7 +20,6 @@
     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 @@
                 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/create.py b/Lib/packaging/create.py
--- a/Lib/packaging/create.py
+++ b/Lib/packaging/create.py
@@ -287,6 +287,7 @@
 
             # 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 @@
                 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 @@
                       ('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 @@
                                  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_command_build_py.py b/Lib/packaging/tests/test_command_build_py.py
--- a/Lib/packaging/tests/test_command_build_py.py
+++ b/Lib/packaging/tests/test_command_build_py.py
@@ -24,11 +24,17 @@
             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 @@
             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 @@
         # 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
--- a/Lib/packaging/tests/test_command_sdist.py
+++ b/Lib/packaging/tests/test_command_sdist.py
@@ -73,7 +73,6 @@
                         'author_email': 'xxx'}
         dist = Distribution(metadata)
         dist.packages = ['somecode']
-        dist.include_package_data = True
         cmd = sdist(dist)
         cmd.dist_dir = 'dist'
         return dist, cmd
diff --git a/Lib/packaging/tests/test_config.py b/Lib/packaging/tests/test_config.py
--- a/Lib/packaging/tests/test_config.py
+++ b/Lib/packaging/tests/test_config.py
@@ -66,11 +66,15 @@
   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 @@
 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 @@
 
         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 @@
         # 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 @@
         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/Lib/packaging/tests/test_create.py b/Lib/packaging/tests/test_create.py
--- a/Lib/packaging/tests/test_create.py
+++ b/Lib/packaging/tests/test_create.py
@@ -116,7 +116,6 @@
               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 @@
                 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 @@
 
             [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
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -466,6 +466,10 @@
 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
   module, like hashlib.  (Patch by Roger Serwy)
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list