Commits

Pierre-Yves David committed c7edf9d Merge

merge with upstream

Comments (0)

Files changed (9)

   one of these Python versions.
 
 - Always run tests.sh before you push a change. This implies
-  that you have all Python versions installed from 2.4 to 2.7.
+  that you have all Python versions installed from 2.4 to 2.7. Be sure to have 
+  docutils installed on all python versions no avoid skipping tests as well.

distutils2/command/check.py

     def check_metadata(self):
         """Ensures that all required elements of metadata are supplied.
 
-        name, version, URL, (author and author_email) or
-        (maintainer and maintainer_email)).
+        name, version, URL, author
 
         Warns if any are missing.
         """
-        missing, __ = self.distribution.metadata.check(strict=True)
+        missing, warnings = self.distribution.metadata.check(strict=True)
         if missing != []:
             self.warn("missing required metadata: %s"  % ', '.join(missing))
+        for warning in warnings:
+            self.warn(warning)
 
     def check_restructuredtext(self):
         """Checks if the long string fields are reST-compliant."""
-        missing, warnings = self.distribution.metadata.check()
+        missing, warnings = self.distribution.metadata.check(restructuredtext=True)
         if self.distribution.metadata.docutils_support:
             for warning in warnings:
                 line = warning[-1].get('line')

distutils2/config.py

 from distutils2.compiler import set_compiler
 from distutils2.command import set_command
 from distutils2.datafiles import resources_dests
+from distutils2.markers import interpret
 
 
 def _pop_values(values_dct, key):
     """Remove values from the dictionary and convert them as a list"""
     vals_str = values_dct.pop(key, '')
+    if not vals_str:
+        return
+    fields = []
+    for field in vals_str.split(os.linesep):
+        tmp_vals = field.split('--')
+        if (len(tmp_vals) == 2) and (not interpret(tmp_vals[1])):
+            continue
+        fields.append(tmp_vals[0])
     # Get bash options like `gcc -print-file-name=libgcc.a`
-    vals = split(vals_str)
+    vals = split(' '.join(fields))
     if vals:
         return vals
 

distutils2/metadata.py

             return None
         return value
 
-    def check(self, strict=False):
+    def check(self, strict=False, restructuredtext=False):
         """Check if the metadata is compliant. If strict is False then raise if
         no Name or Version are provided"""
         # XXX should check the versions (if the file was loaded)
             msg = "missing required metadata: %s"  % ', '.join(missing)
             raise MetadataMissingError(msg)
 
-        for attr in ('Home-page',):
+        for attr in ('Home-page', 'Author'):
             if attr not in self:
                 missing.append(attr)
 
-        if _HAS_DOCUTILS:
+        if _HAS_DOCUTILS and restructuredtext:
             warnings.extend(self._check_rst_data(self['Description']))
 
         # checking metadata 1.2 (XXX needs to check 1.1, 1.0)

distutils2/tests/test_command_check.py

 from distutils2.errors import DistutilsSetupError
 from distutils2.errors import MetadataMissingError
 
+
 class CheckTestCase(support.LoggingCatcher,
                     support.TempdirManager,
                     unittest.TestCase):
 
     def _run(self, metadata=None, **options):
         if metadata is None:
-            metadata = {'name':'xxx', 'version':'xxx'}
+            metadata = {'name': 'xxx', 'version': 'xxx'}
         pkg_info, dist = self.create_dist(**metadata)
         cmd = check(dist)
         cmd.initialize_options()
         # any warning anymore
         metadata = {'home_page': 'xxx', 'author': 'xxx',
                     'author_email': 'xxx',
-                    'name': 'xxx', 'version': 'xxx'
+                    'name': 'xxx', 'version': 'xxx',
                     }
         cmd = self._run(metadata)
         self.assertEqual(len(cmd._warnings), 0)
         # now with the strict mode, we should
         # get an error if there are missing metadata
         self.assertRaises(MetadataMissingError, self._run, {}, **{'strict': 1})
-        self.assertRaises(DistutilsSetupError, self._run, {'name':'xxx', 'version':'xxx'}, **{'strict': 1})
+        self.assertRaises(DistutilsSetupError, self._run,
+            {'name': 'xxx', 'version': 'xxx'}, **{'strict': 1})
 
         # and of course, no error when all metadata fields are present
         cmd = self._run(metadata, strict=1)
         self.assertEqual(len(cmd._warnings), 0)
 
+    def test_check_metadata_1_2(self):
+        # let's run the command with no metadata at all
+        # by default, check is checking the metadata
+        # should have some warnings
+        cmd = self._run()
+        self.assertTrue(len(cmd._warnings) > 0)
+
+        # now let's add the required fields
+        # and run it again, to make sure we don't get
+        # any warning anymore
+        # let's use requires_python as a marker to enforce
+        # Metadata-Version 1.2
+        metadata = {'home_page': 'xxx', 'author': 'xxx',
+                    'author_email': 'xxx',
+                    'name': 'xxx', 'version': 'xxx',
+                    'requires_python': '2.4',
+                    }
+        cmd = self._run(metadata)
+        self.assertEqual(len(cmd._warnings), 1)
+
+        # now with the strict mode, we should
+        # get an error if there are missing metadata
+        self.assertRaises(MetadataMissingError, self._run, {}, **{'strict': 1})
+        self.assertRaises(DistutilsSetupError, self._run,
+            {'name': 'xxx', 'version': 'xxx'}, **{'strict': 1})
+
+        # complain about version format
+        self.assertRaises(DistutilsSetupError, self._run, metadata,
+            **{'strict': 1})
+
+        # now with correct version format
+        metadata = {'home_page': 'xxx', 'author': 'xxx',
+                    'author_email': 'xxx',
+                    'name': 'xxx', 'version': '1.2',
+                    'requires_python': '2.4',
+                    }
+        cmd = self._run(metadata, strict=1)
+        self.assertEqual(len(cmd._warnings), 0)
+
     @unittest.skipUnless(_HAS_DOCUTILS, "requires docutils")
     def test_check_restructuredtext(self):
         # let's see if it detects broken rest in long_description
     def test_check_all(self):
 
         self.assertRaises(DistutilsSetupError, self._run,
-                          {'name':'xxx', 'version':'xxx'}, **{'strict': 1,
+                          {'name': 'xxx', 'version': 'xxx'}, **{'strict': 1,
                                  'all': 1})
         self.assertRaises(MetadataMissingError, self._run,
                           {}, **{'strict': 1,
         cmd = check(dist)
         cmd.check_hooks_resolvable()
         self.assertEqual(len(cmd._warnings), 1)
-        
+
 
 def test_suite():
     return unittest.makeSuite(CheckTestCase)

distutils2/tests/test_config.py

 sources = c_src/speed_coconuts.c
 extra_link_args = "`gcc -print-file-name=libgcc.a`" -shared
 define_macros = HAVE_CAIRO HAVE_GTK2
+libraries = gecodeint gecodekernel -- sys.platform != 'win32'
+    GecodeInt GecodeKernel -- sys.platform == 'win32'
 
 [extension=fast_taunt]
 name = three.fast_taunt
 include_dirs = /usr/include/gecode
     /usr/include/blitz
 extra_compile_args = -fPIC -O2
+    -DGECODE_VERSION=$(./gecode_version) -- sys.platform != 'win32'
+    /DGECODE_VERSION='win32' -- sys.platform == 'win32'
 language = cxx
 
 """
         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'])
+        libs = ['gecodeint', 'gecodekernel']
+        if sys.platform == 'win32':
+            libs = ['GecodeInt', 'GecodeKernel']
+        self.assertEqual(ext.libraries, libs)
         self.assertEqual(ext.extra_link_args,
             ['`gcc -print-file-name=libgcc.a`', '-shared'])
 
             ['cxx_src/utils_taunt.cxx', 'cxx_src/python_module.cxx'])
         self.assertEqual(ext.include_dirs,
             ['/usr/include/gecode', '/usr/include/blitz'])
-        self.assertEqual(ext.extra_compile_args, ['-fPIC', '-O2'])
+        cargs = ['-fPIC', '-O2']
+        if sys.platform == 'win32':
+            cargs.append("/DGECODE_VERSION='win32'")
+        else:
+            cargs.append('-DGECODE_VERSION=$(./gecode_version)')
+        self.assertEqual(ext.extra_compile_args, cargs)
         self.assertEqual(ext.language, 'cxx')
 
 

distutils2/tests/test_metadata.py

                           [('one', 'http://ok')])
         self.assertEqual(metadata.version, '1.2')
 
-    def test_check(self):
+    def test_check_version(self):
+        metadata = DistributionMetadata()
+        metadata['Name'] = 'vimpdb'
+        metadata['Home-page'] = 'http://pypi.python.org'
+        metadata['Author'] = 'Monty Python'
+        metadata.docutils_support = False
+        missing, warnings = metadata.check()
+        self.assertEqual(missing, ['Version'])
+
+    def test_check_version_strict(self):
+        metadata = DistributionMetadata()
+        metadata['Name'] = 'vimpdb'
+        metadata['Home-page'] = 'http://pypi.python.org'
+        metadata['Author'] = 'Monty Python'
+        metadata.docutils_support = False
+        from distutils2.errors import MetadataMissingError
+        self.assertRaises(MetadataMissingError, metadata.check, strict=True)
+
+    def test_check_name(self):
+        metadata = DistributionMetadata()
+        metadata['Version'] = '1.0'
+        metadata['Home-page'] = 'http://pypi.python.org'
+        metadata['Author'] = 'Monty Python'
+        metadata.docutils_support = False
+        missing, warnings = metadata.check()
+        self.assertEqual(missing, ['Name'])
+
+    def test_check_name_strict(self):
+        metadata = DistributionMetadata()
+        metadata['Version'] = '1.0'
+        metadata['Home-page'] = 'http://pypi.python.org'
+        metadata['Author'] = 'Monty Python'
+        metadata.docutils_support = False
+        from distutils2.errors import MetadataMissingError
+        self.assertRaises(MetadataMissingError, metadata.check, strict=True)
+
+    def test_check_author(self):
+        metadata = DistributionMetadata()
+        metadata['Version'] = '1.0'
+        metadata['Name'] = 'vimpdb'
+        metadata['Home-page'] = 'http://pypi.python.org'
+        metadata.docutils_support = False
+        missing, warnings = metadata.check()
+        self.assertEqual(missing, ['Author'])
+
+    def test_check_homepage(self):
+        metadata = DistributionMetadata()
+        metadata['Version'] = '1.0'
+        metadata['Name'] = 'vimpdb'
+        metadata['Author'] = 'Monty Python'
+        metadata.docutils_support = False
+        missing, warnings = metadata.check()
+        self.assertEqual(missing, ['Home-page'])
+
+    def test_check_predicates(self):
         metadata = DistributionMetadata()
         metadata['Version'] = 'rr'
+        metadata['Name'] = 'vimpdb'
+        metadata['Home-page'] = 'http://pypi.python.org'
+        metadata['Author'] = 'Monty Python'
         metadata['Requires-dist'] = ['Foo (a)']
+        metadata['Obsoletes-dist'] = ['Foo (a)']
+        metadata['Provides-dist'] = ['Foo (a)']
         if metadata.docutils_support:
             missing, warnings = metadata.check()
-            self.assertEqual(len(warnings), 2)
+            self.assertEqual(len(warnings), 4)
             metadata.docutils_support = False
         missing, warnings = metadata.check()
-        self.assertEqual(missing, ['Name', 'Home-page'])
-        self.assertEqual(len(warnings), 2)
+        self.assertEqual(len(warnings), 4)
 
     def test_best_choice(self):
         metadata = DistributionMetadata()

distutils2/util.py

     cmd = ' '.join(cmd)
     if verbose:
         logger.info(cmd)
-        logger.info(env)
     if dry_run:
         return
     exit_status = sub_call(cmd, shell=True, env=env)
             # There is no such option in the setup.cfg
             if arg == "long_description":
                 filename = has_get_option(config, section, "description_file")
-                print "We have a filename", filename
                 if filename:
                     in_cfg_value = open(filename).read()
             else:
         raise DistutilsFileError("A pre existing setup.py file exists")
 
     handle = open("setup.py", "w")
-    handle.write("# Distutils script using distutils2 setup.cfg to call the\n")
-    handle.write("# distutils.core.setup() with the right args.\n\n\n")
-    handle.write("import os\n")
-    handle.write("from distutils.core import setup\n")
-    handle.write("from ConfigParser import RawConfigParser\n\n")
-    handle.write(getsource(generate_distutils_kwargs_from_setup_cfg))
-    handle.write("\n\nkwargs = generate_distutils_kwargs_from_setup_cfg()\n")
-    handle.write("setup(**kwargs)")
-    handle.close()
+    try:
+        handle.write(
+            "# Distutils script using distutils2 setup.cfg to call the\n"
+            "# distutils.core.setup() with the right args.\n\n"
+            "import os\n"
+            "from distutils.core import setup\n"
+            "from ConfigParser import RawConfigParser\n\n"
+            "" + getsource(generate_distutils_kwargs_from_setup_cfg) + "\n\n"
+            "kwargs = generate_distutils_kwargs_from_setup_cfg()\n"
+            "setup(**kwargs)\n"
+        )
+    finally:
+        handle.close()

docs/source/contributing.rst

+==========================
+Contributing to Distutils2
+==========================
+
+----------------
+Reporting Issues
+----------------
+
+When using, testing, developping distutils2, you may encounter issues. Please report to the following sections to know how these issues should be reported.
+
+Please keep in mind that this guide is intended to ease the triage and fixing processes by giving the maximum information to the developers. It should not be viewed as mandatory, only advised ;).
+
+Issues regarding distutils2 commands
+====================================
+
+- Go to http://bugs.python.org/ (you'll need a Python Bugs account), then "Issues" > "Create ticket".
+- **Title**: write in a short summary of the issue. 
+    * You may prefix the issue title with [d2_component], where d2_component can be : installer, sdist, setup.cfg, ... This will ease up the triage process.
+
+- **Components**: choose "Distutils2"
+- **Version**: choose "3rd party"
+- **Comment**: use the following template for versions, reproduction conditions:
+    * If some of the fields presented don't apply to the issue, feel free to pick only the ones you need.
+
+::
+
+    Operating System:
+    Version of Python:
+    Version of Distutils2:
+
+    How to reproduce:
+
+    What happens:
+
+    What should happen:
+
+- Filling in the fields:
+    * **How to reproduce**: indicate some test case to reproduce the issue.
+    * **What happens**: describe what is the error, paste tracebacks if you have any.
+    * **What should happen**: indicate what you think should be the result of the test case (wanted behaviour).
+    * **Versions**:
+        - If you're using a release of distutils2, you may want to test the latest version of the project (under developpment code).
+        - If the issue is present in the latest version, please indicate the tip commit of the version tested.
+        - Be careful to indicate the remote reference (12 characters, for instance c3cf81fc64db), not the local reference (rXXX).
+
+- If it is relevant, please join any file that will help reproducing the issue or logs to understand the problem (setup.cfg, strace ouptups, ...).
+
+Issues regarding PyPI display of the distutils2 projects
+========================================================
+
+- Please send a bug report to the catalog-sig@python.org mailing list.
+- You can include your setup.cfg, and a link to your project page.