We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
setuptools wheel install will fail if a data dir is a subdirectory in a package
With the new wheel support, I ran into an issue where if `data_files` specifies a subdirectory in a package, `setuptools` will fail on moving the data.  This worked in previous versions of setuptools w/o wheel support, and also works with pip install.

Perhaps this is not a supported use case (should `package_data` be used instead?)

I was able to work around the issue by removing the subdirectory, but in case someone else runs into this, here is a repro test case that can be added to `test_wheel.py`


```
    dict(
        id='data_in_package',
        file_defs={
            'foo': {
                '__init__.py': '',
                'data_dir': {
                    'data.txt': DALS(
                        '''
                        Some data...
                        '''
                    ),
                }
            }
        },
        setup_kwargs=dict(
            packages=['foo'],
            data_files=[('foo/data_dir', ['foo/data_dir/data.txt'])],
        ),
        install_tree=DALS(
            '''
            foo-1.0-py{py_version}.egg/
            |-- EGG-INFO/
            |  |-- DESCRIPTION.rst
            |  |-- PKG-INFO
            |  |-- RECORD
            |  |-- WHEEL
            |  |-- metadata.json
            |  |-- top_level.txt
            |-- foo/
            |  |-- __init__.py
            |  |-- data_dir/
            |     |-- data.txt
            '''
        ),
    ),
```

In the test case, `foo` is a package and `/foo/data_dir/` is a data dir. Since `foo` already exists as a package, the `os.rename` fails, even though `/foo/data_dir/` does not exist. Should it check if the directory already exists?

The error looks something like the following (on OSX):

```
                for entry in os.listdir(subdir):
                    os.rename(os.path.join(subdir, entry),
>                             os.path.join(destination_eggdir, entry))
E                   OSError: [Errno 66] Directory not empty: '/var/folders/07/c66dj8613n37ssnxsvyz8dcm0000gn/T/tmpybp6f4ft/foo-1.0-py3.5.egg/foo-1.0.data/data/foo' -> '/var/folders/07/c66dj8613n37ssnxsvyz8dcm0000gn/T/tmpybp6f4ft/foo-1.0-py3.5.egg/foo'
```





--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `setuptools/wheel.py`
Content:
```
1 '''Wheels support.'''
2 
3 from distutils.util import get_platform
4 import email
5 import itertools
6 import os
7 import re
8 import zipfile
9 
10 from pkg_resources import Distribution, PathMetadata, parse_version
11 from pkg_resources.extern.six import PY3
12 from setuptools import Distribution as SetuptoolsDistribution
13 from setuptools import pep425tags
14 from setuptools.command.egg_info import write_requirements
15 
16 
17 WHEEL_NAME = re.compile(
18     r"""^(?P<project_name>.+?)-(?P<version>\d.*?)
19     ((-(?P<build>\d.*?))?-(?P<py_version>.+?)-(?P<abi>.+?)-(?P<platform>.+?)
20     )\.whl$""",
21 re.VERBOSE).match
22 
23 NAMESPACE_PACKAGE_INIT = '''\
24 try:
25     __import__('pkg_resources').declare_namespace(__name__)
26 except ImportError:
27     __path__ = __import__('pkgutil').extend_path(__path__, __name__)
28 '''
29 
30 
31 class Wheel(object):
32 
33     def __init__(self, filename):
34         match = WHEEL_NAME(os.path.basename(filename))
35         if match is None:
36             raise ValueError('invalid wheel name: %r' % filename)
37         self.filename = filename
38         for k, v in match.groupdict().items():
39             setattr(self, k, v)
40 
41     def tags(self):
42         '''List tags (py_version, abi, platform) supported by this wheel.'''
43         return itertools.product(self.py_version.split('.'),
44                                  self.abi.split('.'),
45                                  self.platform.split('.'))
46 
47     def is_compatible(self):
48         '''Is the wheel is compatible with the current platform?'''
49         supported_tags = pep425tags.get_supported()
50         return next((True for t in self.tags() if t in supported_tags), False)
51 
52     def egg_name(self):
53         return Distribution(
54             project_name=self.project_name, version=self.version,
55             platform=(None if self.platform == 'any' else get_platform()),
56         ).egg_name() + '.egg'
57 
58     def install_as_egg(self, destination_eggdir):
59         '''Install wheel as an egg directory.'''
60         with zipfile.ZipFile(self.filename) as zf:
61             dist_basename = '%s-%s' % (self.project_name, self.version)
62             dist_info = '%s.dist-info' % dist_basename
63             dist_data = '%s.data' % dist_basename
64             def get_metadata(name):
65                 with zf.open('%s/%s' % (dist_info, name)) as fp:
66                     value = fp.read().decode('utf-8') if PY3 else fp.read()
67                     return email.parser.Parser().parsestr(value)
68             wheel_metadata = get_metadata('WHEEL')
69             dist_metadata = get_metadata('METADATA')
70             # Check wheel format version is supported.
71             wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))
72             if not parse_version('1.0') <= wheel_version < parse_version('2.0dev0'):
73                 raise ValueError('unsupported wheel format version: %s' % wheel_version)
74             # Extract to target directory.
75             os.mkdir(destination_eggdir)
76             zf.extractall(destination_eggdir)
77             # Convert metadata.
78             dist_info = os.path.join(destination_eggdir, dist_info)
79             dist = Distribution.from_location(
80                 destination_eggdir, dist_info,
81                 metadata=PathMetadata(destination_eggdir, dist_info)
82             )
83             # Note: we need to evaluate and strip markers now,
84             # as we can't easily convert back from the syntax:
85             # foobar; "linux" in sys_platform and extra == 'test'
86             def raw_req(req):
87                 req.marker = None
88                 return str(req)
89             install_requires = list(sorted(map(raw_req, dist.requires())))
90             extras_require = {
91                 extra: list(sorted(
92                     req
93                     for req in map(raw_req, dist.requires((extra,)))
94                     if req not in install_requires
95                 ))
96                 for extra in dist.extras
97             }
98             egg_info = os.path.join(destination_eggdir, 'EGG-INFO')
99             os.rename(dist_info, egg_info)
100             os.rename(os.path.join(egg_info, 'METADATA'),
101                       os.path.join(egg_info, 'PKG-INFO'))
102             setup_dist = SetuptoolsDistribution(attrs=dict(
103                 install_requires=install_requires,
104                 extras_require=extras_require,
105             ))
106             write_requirements(setup_dist.get_command_obj('egg_info'),
107                                None, os.path.join(egg_info, 'requires.txt'))
108             # Move data entries to their correct location.
109             dist_data = os.path.join(destination_eggdir, dist_data)
110             dist_data_scripts = os.path.join(dist_data, 'scripts')
111             if os.path.exists(dist_data_scripts):
112                 egg_info_scripts = os.path.join(destination_eggdir,
113                                                 'EGG-INFO', 'scripts')
114                 os.mkdir(egg_info_scripts)
115                 for entry in os.listdir(dist_data_scripts):
116                     # Remove bytecode, as it's not properly handled
117                     # during easy_install scripts install phase.
118                     if entry.endswith('.pyc'):
119                         os.unlink(os.path.join(dist_data_scripts, entry))
120                     else:
121                         os.rename(os.path.join(dist_data_scripts, entry),
122                                   os.path.join(egg_info_scripts, entry))
123                 os.rmdir(dist_data_scripts)
124             for subdir in filter(os.path.exists, (
125                 os.path.join(dist_data, d)
126                 for d in ('data', 'headers', 'purelib', 'platlib')
127             )):
128                 for entry in os.listdir(subdir):
129                     os.rename(os.path.join(subdir, entry),
130                               os.path.join(destination_eggdir, entry))
131                 os.rmdir(subdir)
132             if os.path.exists(dist_data):
133                 os.rmdir(dist_data)
134             # Fix namespace packages.
135             namespace_packages = os.path.join(egg_info, 'namespace_packages.txt')
136             if os.path.exists(namespace_packages):
137                 with open(namespace_packages) as fp:
138                     namespace_packages = fp.read().split()
139                 for mod in namespace_packages:
140                     mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
141                     mod_init = os.path.join(mod_dir, '__init__.py')
142                     if os.path.exists(mod_dir) and not os.path.exists(mod_init):
143                         with open(mod_init, 'w') as fp:
144                             fp.write(NAMESPACE_PACKAGE_INIT)
145
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/setuptools/wheel.py b/setuptools/wheel.py
--- a/setuptools/wheel.py
+++ b/setuptools/wheel.py
@@ -28,6 +28,28 @@
 '''
 
 
+def unpack(src_dir, dst_dir):
+    '''Move everything under `src_dir` to `dst_dir`, and delete the former.'''
+    for dirpath, dirnames, filenames in os.walk(src_dir):
+        subdir = os.path.relpath(dirpath, src_dir)
+        for f in filenames:
+            src = os.path.join(dirpath, f)
+            dst = os.path.join(dst_dir, subdir, f)
+            os.renames(src, dst)
+        for n, d in reversed(list(enumerate(dirnames))):
+            src = os.path.join(dirpath, d)
+            dst = os.path.join(dst_dir, subdir, d)
+            if not os.path.exists(dst):
+                # Directory does not exist in destination,
+                # rename it and prune it from os.walk list.
+                os.renames(src, dst)
+                del dirnames[n]
+    # Cleanup.
+    for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True):
+        assert not filenames
+        os.rmdir(dirpath)
+
+
 class Wheel(object):
 
     def __init__(self, filename):
@@ -125,10 +147,7 @@
                 os.path.join(dist_data, d)
                 for d in ('data', 'headers', 'purelib', 'platlib')
             )):
-                for entry in os.listdir(subdir):
-                    os.rename(os.path.join(subdir, entry),
-                              os.path.join(destination_eggdir, entry))
-                os.rmdir(subdir)
+                unpack(subdir, destination_eggdir)
             if os.path.exists(dist_data):
                 os.rmdir(dist_data)
             # Fix namespace packages.

{"golden_diff": "diff --git a/setuptools/wheel.py b/setuptools/wheel.py\n--- a/setuptools/wheel.py\n+++ b/setuptools/wheel.py\n@@ -28,6 +28,28 @@\n '''\n \n \n+def unpack(src_dir, dst_dir):\n+    '''Move everything under `src_dir` to `dst_dir`, and delete the former.'''\n+    for dirpath, dirnames, filenames in os.walk(src_dir):\n+        subdir = os.path.relpath(dirpath, src_dir)\n+        for f in filenames:\n+            src = os.path.join(dirpath, f)\n+            dst = os.path.join(dst_dir, subdir, f)\n+            os.renames(src, dst)\n+        for n, d in reversed(list(enumerate(dirnames))):\n+            src = os.path.join(dirpath, d)\n+            dst = os.path.join(dst_dir, subdir, d)\n+            if not os.path.exists(dst):\n+                # Directory does not exist in destination,\n+                # rename it and prune it from os.walk list.\n+                os.renames(src, dst)\n+                del dirnames[n]\n+    # Cleanup.\n+    for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True):\n+        assert not filenames\n+        os.rmdir(dirpath)\n+\n+\n class Wheel(object):\n \n     def __init__(self, filename):\n@@ -125,10 +147,7 @@\n                 os.path.join(dist_data, d)\n                 for d in ('data', 'headers', 'purelib', 'platlib')\n             )):\n-                for entry in os.listdir(subdir):\n-                    os.rename(os.path.join(subdir, entry),\n-                              os.path.join(destination_eggdir, entry))\n-                os.rmdir(subdir)\n+                unpack(subdir, destination_eggdir)\n             if os.path.exists(dist_data):\n                 os.rmdir(dist_data)\n             # Fix namespace packages.\n", "issue": "setuptools wheel install will fail if a data dir is a subdirectory in a package\nWith the new wheel support, I ran into an issue where if `data_files` specifies a subdirectory in a package, `setuptools` will fail on moving the data.  This worked in previous versions of setuptools w/o wheel support, and also works with pip install.\r\n\r\nPerhaps this is not a supported use case (should `package_data` be used instead?)\r\n\r\nI was able to work around the issue by removing the subdirectory, but in case someone else runs into this, here is a repro test case that can be added to `test_wheel.py`\r\n\r\n\r\n```\r\n    dict(\r\n        id='data_in_package',\r\n        file_defs={\r\n            'foo': {\r\n                '__init__.py': '',\r\n                'data_dir': {\r\n                    'data.txt': DALS(\r\n                        '''\r\n                        Some data...\r\n                        '''\r\n                    ),\r\n                }\r\n            }\r\n        },\r\n        setup_kwargs=dict(\r\n            packages=['foo'],\r\n            data_files=[('foo/data_dir', ['foo/data_dir/data.txt'])],\r\n        ),\r\n        install_tree=DALS(\r\n            '''\r\n            foo-1.0-py{py_version}.egg/\r\n            |-- EGG-INFO/\r\n            |  |-- DESCRIPTION.rst\r\n            |  |-- PKG-INFO\r\n            |  |-- RECORD\r\n            |  |-- WHEEL\r\n            |  |-- metadata.json\r\n            |  |-- top_level.txt\r\n            |-- foo/\r\n            |  |-- __init__.py\r\n            |  |-- data_dir/\r\n            |     |-- data.txt\r\n            '''\r\n        ),\r\n    ),\r\n```\r\n\r\nIn the test case, `foo` is a package and `/foo/data_dir/` is a data dir. Since `foo` already exists as a package, the `os.rename` fails, even though `/foo/data_dir/` does not exist. Should it check if the directory already exists?\r\n\r\nThe error looks something like the following (on OSX):\r\n\r\n```\r\n                for entry in os.listdir(subdir):\r\n                    os.rename(os.path.join(subdir, entry),\r\n>                             os.path.join(destination_eggdir, entry))\r\nE                   OSError: [Errno 66] Directory not empty: '/var/folders/07/c66dj8613n37ssnxsvyz8dcm0000gn/T/tmpybp6f4ft/foo-1.0-py3.5.egg/foo-1.0.data/data/foo' -> '/var/folders/07/c66dj8613n37ssnxsvyz8dcm0000gn/T/tmpybp6f4ft/foo-1.0-py3.5.egg/foo'\r\n```\r\n\r\n\r\n\r\n\n", "before_files": [{"content": "'''Wheels support.'''\n\nfrom distutils.util import get_platform\nimport email\nimport itertools\nimport os\nimport re\nimport zipfile\n\nfrom pkg_resources import Distribution, PathMetadata, parse_version\nfrom pkg_resources.extern.six import PY3\nfrom setuptools import Distribution as SetuptoolsDistribution\nfrom setuptools import pep425tags\nfrom setuptools.command.egg_info import write_requirements\n\n\nWHEEL_NAME = re.compile(\n    r\"\"\"^(?P<project_name>.+?)-(?P<version>\\d.*?)\n    ((-(?P<build>\\d.*?))?-(?P<py_version>.+?)-(?P<abi>.+?)-(?P<platform>.+?)\n    )\\.whl$\"\"\",\nre.VERBOSE).match\n\nNAMESPACE_PACKAGE_INIT = '''\\\ntry:\n    __import__('pkg_resources').declare_namespace(__name__)\nexcept ImportError:\n    __path__ = __import__('pkgutil').extend_path(__path__, __name__)\n'''\n\n\nclass Wheel(object):\n\n    def __init__(self, filename):\n        match = WHEEL_NAME(os.path.basename(filename))\n        if match is None:\n            raise ValueError('invalid wheel name: %r' % filename)\n        self.filename = filename\n        for k, v in match.groupdict().items():\n            setattr(self, k, v)\n\n    def tags(self):\n        '''List tags (py_version, abi, platform) supported by this wheel.'''\n        return itertools.product(self.py_version.split('.'),\n                                 self.abi.split('.'),\n                                 self.platform.split('.'))\n\n    def is_compatible(self):\n        '''Is the wheel is compatible with the current platform?'''\n        supported_tags = pep425tags.get_supported()\n        return next((True for t in self.tags() if t in supported_tags), False)\n\n    def egg_name(self):\n        return Distribution(\n            project_name=self.project_name, version=self.version,\n            platform=(None if self.platform == 'any' else get_platform()),\n        ).egg_name() + '.egg'\n\n    def install_as_egg(self, destination_eggdir):\n        '''Install wheel as an egg directory.'''\n        with zipfile.ZipFile(self.filename) as zf:\n            dist_basename = '%s-%s' % (self.project_name, self.version)\n            dist_info = '%s.dist-info' % dist_basename\n            dist_data = '%s.data' % dist_basename\n            def get_metadata(name):\n                with zf.open('%s/%s' % (dist_info, name)) as fp:\n                    value = fp.read().decode('utf-8') if PY3 else fp.read()\n                    return email.parser.Parser().parsestr(value)\n            wheel_metadata = get_metadata('WHEEL')\n            dist_metadata = get_metadata('METADATA')\n            # Check wheel format version is supported.\n            wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))\n            if not parse_version('1.0') <= wheel_version < parse_version('2.0dev0'):\n                raise ValueError('unsupported wheel format version: %s' % wheel_version)\n            # Extract to target directory.\n            os.mkdir(destination_eggdir)\n            zf.extractall(destination_eggdir)\n            # Convert metadata.\n            dist_info = os.path.join(destination_eggdir, dist_info)\n            dist = Distribution.from_location(\n                destination_eggdir, dist_info,\n                metadata=PathMetadata(destination_eggdir, dist_info)\n            )\n            # Note: we need to evaluate and strip markers now,\n            # as we can't easily convert back from the syntax:\n            # foobar; \"linux\" in sys_platform and extra == 'test'\n            def raw_req(req):\n                req.marker = None\n                return str(req)\n            install_requires = list(sorted(map(raw_req, dist.requires())))\n            extras_require = {\n                extra: list(sorted(\n                    req\n                    for req in map(raw_req, dist.requires((extra,)))\n                    if req not in install_requires\n                ))\n                for extra in dist.extras\n            }\n            egg_info = os.path.join(destination_eggdir, 'EGG-INFO')\n            os.rename(dist_info, egg_info)\n            os.rename(os.path.join(egg_info, 'METADATA'),\n                      os.path.join(egg_info, 'PKG-INFO'))\n            setup_dist = SetuptoolsDistribution(attrs=dict(\n                install_requires=install_requires,\n                extras_require=extras_require,\n            ))\n            write_requirements(setup_dist.get_command_obj('egg_info'),\n                               None, os.path.join(egg_info, 'requires.txt'))\n            # Move data entries to their correct location.\n            dist_data = os.path.join(destination_eggdir, dist_data)\n            dist_data_scripts = os.path.join(dist_data, 'scripts')\n            if os.path.exists(dist_data_scripts):\n                egg_info_scripts = os.path.join(destination_eggdir,\n                                                'EGG-INFO', 'scripts')\n                os.mkdir(egg_info_scripts)\n                for entry in os.listdir(dist_data_scripts):\n                    # Remove bytecode, as it's not properly handled\n                    # during easy_install scripts install phase.\n                    if entry.endswith('.pyc'):\n                        os.unlink(os.path.join(dist_data_scripts, entry))\n                    else:\n                        os.rename(os.path.join(dist_data_scripts, entry),\n                                  os.path.join(egg_info_scripts, entry))\n                os.rmdir(dist_data_scripts)\n            for subdir in filter(os.path.exists, (\n                os.path.join(dist_data, d)\n                for d in ('data', 'headers', 'purelib', 'platlib')\n            )):\n                for entry in os.listdir(subdir):\n                    os.rename(os.path.join(subdir, entry),\n                              os.path.join(destination_eggdir, entry))\n                os.rmdir(subdir)\n            if os.path.exists(dist_data):\n                os.rmdir(dist_data)\n            # Fix namespace packages.\n            namespace_packages = os.path.join(egg_info, 'namespace_packages.txt')\n            if os.path.exists(namespace_packages):\n                with open(namespace_packages) as fp:\n                    namespace_packages = fp.read().split()\n                for mod in namespace_packages:\n                    mod_dir = os.path.join(destination_eggdir, *mod.split('.'))\n                    mod_init = os.path.join(mod_dir, '__init__.py')\n                    if os.path.exists(mod_dir) and not os.path.exists(mod_init):\n                        with open(mod_init, 'w') as fp:\n                            fp.write(NAMESPACE_PACKAGE_INIT)\n", "path": "setuptools/wheel.py"}], "after_files": [{"content": "'''Wheels support.'''\n\nfrom distutils.util import get_platform\nimport email\nimport itertools\nimport os\nimport re\nimport zipfile\n\nfrom pkg_resources import Distribution, PathMetadata, parse_version\nfrom pkg_resources.extern.six import PY3\nfrom setuptools import Distribution as SetuptoolsDistribution\nfrom setuptools import pep425tags\nfrom setuptools.command.egg_info import write_requirements\n\n\nWHEEL_NAME = re.compile(\n    r\"\"\"^(?P<project_name>.+?)-(?P<version>\\d.*?)\n    ((-(?P<build>\\d.*?))?-(?P<py_version>.+?)-(?P<abi>.+?)-(?P<platform>.+?)\n    )\\.whl$\"\"\",\nre.VERBOSE).match\n\nNAMESPACE_PACKAGE_INIT = '''\\\ntry:\n    __import__('pkg_resources').declare_namespace(__name__)\nexcept ImportError:\n    __path__ = __import__('pkgutil').extend_path(__path__, __name__)\n'''\n\n\ndef unpack(src_dir, dst_dir):\n    '''Move everything under `src_dir` to `dst_dir`, and delete the former.'''\n    for dirpath, dirnames, filenames in os.walk(src_dir):\n        subdir = os.path.relpath(dirpath, src_dir)\n        for f in filenames:\n            src = os.path.join(dirpath, f)\n            dst = os.path.join(dst_dir, subdir, f)\n            os.renames(src, dst)\n        for n, d in reversed(list(enumerate(dirnames))):\n            src = os.path.join(dirpath, d)\n            dst = os.path.join(dst_dir, subdir, d)\n            if not os.path.exists(dst):\n                # Directory does not exist in destination,\n                # rename it and prune it from os.walk list.\n                os.renames(src, dst)\n                del dirnames[n]\n    # Cleanup.\n    for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True):\n        assert not filenames\n        os.rmdir(dirpath)\n\n\nclass Wheel(object):\n\n    def __init__(self, filename):\n        match = WHEEL_NAME(os.path.basename(filename))\n        if match is None:\n            raise ValueError('invalid wheel name: %r' % filename)\n        self.filename = filename\n        for k, v in match.groupdict().items():\n            setattr(self, k, v)\n\n    def tags(self):\n        '''List tags (py_version, abi, platform) supported by this wheel.'''\n        return itertools.product(self.py_version.split('.'),\n                                 self.abi.split('.'),\n                                 self.platform.split('.'))\n\n    def is_compatible(self):\n        '''Is the wheel is compatible with the current platform?'''\n        supported_tags = pep425tags.get_supported()\n        return next((True for t in self.tags() if t in supported_tags), False)\n\n    def egg_name(self):\n        return Distribution(\n            project_name=self.project_name, version=self.version,\n            platform=(None if self.platform == 'any' else get_platform()),\n        ).egg_name() + '.egg'\n\n    def install_as_egg(self, destination_eggdir):\n        '''Install wheel as an egg directory.'''\n        with zipfile.ZipFile(self.filename) as zf:\n            dist_basename = '%s-%s' % (self.project_name, self.version)\n            dist_info = '%s.dist-info' % dist_basename\n            dist_data = '%s.data' % dist_basename\n            def get_metadata(name):\n                with zf.open('%s/%s' % (dist_info, name)) as fp:\n                    value = fp.read().decode('utf-8') if PY3 else fp.read()\n                    return email.parser.Parser().parsestr(value)\n            wheel_metadata = get_metadata('WHEEL')\n            dist_metadata = get_metadata('METADATA')\n            # Check wheel format version is supported.\n            wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))\n            if not parse_version('1.0') <= wheel_version < parse_version('2.0dev0'):\n                raise ValueError('unsupported wheel format version: %s' % wheel_version)\n            # Extract to target directory.\n            os.mkdir(destination_eggdir)\n            zf.extractall(destination_eggdir)\n            # Convert metadata.\n            dist_info = os.path.join(destination_eggdir, dist_info)\n            dist = Distribution.from_location(\n                destination_eggdir, dist_info,\n                metadata=PathMetadata(destination_eggdir, dist_info)\n            )\n            # Note: we need to evaluate and strip markers now,\n            # as we can't easily convert back from the syntax:\n            # foobar; \"linux\" in sys_platform and extra == 'test'\n            def raw_req(req):\n                req.marker = None\n                return str(req)\n            install_requires = list(sorted(map(raw_req, dist.requires())))\n            extras_require = {\n                extra: list(sorted(\n                    req\n                    for req in map(raw_req, dist.requires((extra,)))\n                    if req not in install_requires\n                ))\n                for extra in dist.extras\n            }\n            egg_info = os.path.join(destination_eggdir, 'EGG-INFO')\n            os.rename(dist_info, egg_info)\n            os.rename(os.path.join(egg_info, 'METADATA'),\n                      os.path.join(egg_info, 'PKG-INFO'))\n            setup_dist = SetuptoolsDistribution(attrs=dict(\n                install_requires=install_requires,\n                extras_require=extras_require,\n            ))\n            write_requirements(setup_dist.get_command_obj('egg_info'),\n                               None, os.path.join(egg_info, 'requires.txt'))\n            # Move data entries to their correct location.\n            dist_data = os.path.join(destination_eggdir, dist_data)\n            dist_data_scripts = os.path.join(dist_data, 'scripts')\n            if os.path.exists(dist_data_scripts):\n                egg_info_scripts = os.path.join(destination_eggdir,\n                                                'EGG-INFO', 'scripts')\n                os.mkdir(egg_info_scripts)\n                for entry in os.listdir(dist_data_scripts):\n                    # Remove bytecode, as it's not properly handled\n                    # during easy_install scripts install phase.\n                    if entry.endswith('.pyc'):\n                        os.unlink(os.path.join(dist_data_scripts, entry))\n                    else:\n                        os.rename(os.path.join(dist_data_scripts, entry),\n                                  os.path.join(egg_info_scripts, entry))\n                os.rmdir(dist_data_scripts)\n            for subdir in filter(os.path.exists, (\n                os.path.join(dist_data, d)\n                for d in ('data', 'headers', 'purelib', 'platlib')\n            )):\n                unpack(subdir, destination_eggdir)\n            if os.path.exists(dist_data):\n                os.rmdir(dist_data)\n            # Fix namespace packages.\n            namespace_packages = os.path.join(egg_info, 'namespace_packages.txt')\n            if os.path.exists(namespace_packages):\n                with open(namespace_packages) as fp:\n                    namespace_packages = fp.read().split()\n                for mod in namespace_packages:\n                    mod_dir = os.path.join(destination_eggdir, *mod.split('.'))\n                    mod_init = os.path.join(mod_dir, '__init__.py')\n                    if os.path.exists(mod_dir) and not os.path.exists(mod_init):\n                        with open(mod_init, 'w') as fp:\n                            fp.write(NAMESPACE_PACKAGE_INIT)\n", "path": "setuptools/wheel.py"}]}