Repository: pypa/setuptools (Python)

Issue:
Spurious "Provides-Extra:" generated in metadata
In the recently released version of setuptools, when installing my distribution [copyingmock](https://pypi.python.org/packages/e7/4b/857c745721ed3d5dc33c426d6e31aaff13a5cd5caaf444117139b2d9936f/copyingmock-0.2.tar.gz#md5=9aa6ba13542d25e527fe358d53cdaf3b), it claims that it provides the `extras=['']`.  Of course, I don't provide the empty-string extra, and the correct metadata should be `extras=[]`.  This seems to be related to [using the conditional deps feature](https://github.com/wimglenn/copyingmock/blob/c80ec21e80a733138b99eed6020563ceae8c20ef/setup.py#L26), somehow:

    install_requires=["mock ; python_version<'3.3'"],

To reproduce the issue, you can get the sdist:

    $ pip download copyingmock==0.2 --no-binary copyingmock

Then use `git bisect` with this script:

```
#!/usr/bin/env python
# check.py
import json
import subprocess
import sys
from zipfile import ZipFile

if __name__ == '__main__':
    subprocess.check_call(['pip', 'wheel', '--no-deps', '--no-index', './copyingmock-0.2.tar.gz'])
    whl = ZipFile('copyingmock-0.2-py2.py3-none-any.whl')
    metadata = json.loads(whl.read('copyingmock-0.2.dist-info/metadata.json'))
    print(metadata['extras'])

    if metadata['extras']:
        sys.exit(1)
    else:
        sys.exit(0)
```

I did bisect and found 

    $ git bisect start
    $ git bisect bad tags/v38.6.0
    $ git bisect good tags/v28.8.0
    Bisecting: 375 revisions left to test after this (roughly 9 steps)
    [2cd7f22eb62b413d65fe4208d66f7e2738f71a56] Correctly honor exist_ok. Ref #1083.
    $ git bisect run ./check.py
    ...

https://github.com/pypa/setuptools/commit/b2ea3c4a20d008622caec445f5b6916ddd420d16 is the first bad commit.



Discussion:

Patch:
diff --git a/setuptools/dist.py b/setuptools/dist.py
index 33ceb40426..d24958daae 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -389,7 +389,9 @@ def _finalize_requires(self):
                 # Since this gets called multiple times at points where the
                 # keys have become 'converted' extras, ensure that we are only
                 # truly adding extras we haven't seen before here.
-                self.metadata.provides_extras.add(extra.split(':')[0])
+                extra = extra.split(':')[0]
+                if extra:
+                    self.metadata.provides_extras.add(extra)
 
         self._convert_extras_requirements()
         self._move_install_requirements_markers()


Test patch:
diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py
index ff5fa0a30b..d221167152 100644
--- a/setuptools/tests/test_egg_info.py
+++ b/setuptools/tests/test_egg_info.py
@@ -438,6 +438,23 @@ def test_provides_extra(self, tmpdir_cwd, env):
         assert 'Provides-Extra: foobar' in pkg_info_lines
         assert 'Metadata-Version: 2.1' in pkg_info_lines
 
+    def test_doesnt_provides_extra(self, tmpdir_cwd, env):
+        self._setup_script_with_requires(
+            '''install_requires=["spam ; python_version<'3.3'"]''')
+        environ = os.environ.copy().update(
+            HOME=env.paths['home'],
+        )
+        environment.run_setup_py(
+            cmd=['egg_info'],
+            pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]),
+            data_stream=1,
+            env=environ,
+        )
+        egg_info_dir = os.path.join('.', 'foo.egg-info')
+        with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file:
+            pkg_info_text = pkginfo_file.read()
+        assert 'Provides-Extra:' not in pkg_info_text
+
     def test_long_description_content_type(self, tmpdir_cwd, env):
         # Test that specifying a `long_description_content_type` keyword arg to
         # the `setup` function results in writing a `Description-Content-Type`