We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
mtime set to 0 on setup.py and PKG-INFO in sdist package
<!--
  Hi there! Thank you for discovering and submitting an issue.

  Before you submit this; let's make sure of a few things.
  Please make sure the following boxes are ticked if they are correct.
  If not, please try and fulfill these first.
-->

<!-- Checked checkbox should look like this: [x] -->
- [x] I am on the [latest](https://github.com/sdispater/poetry/releases/latest) Poetry version.
- [x] I have searched the [issues](https://github.com/sdispater/poetry/issues) of this repo and believe that this is not a duplicate.
- [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option).

<!--
  Once those are done, if you're able to fill in the following list with your information,
  it'd be very helpful to whoever handles the issue.
-->

- **OS version and name**: Ubuntu 18.04.1 LTS
- **Poetry version**: 0.12.10
- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**: <!-- Gist Link Here -->

## Issue
<!-- Now feel free to write your issue, but please be descriptive! Thanks again 🙌 ❤️ -->
`poetry build` creates an `sdist` tarball. If you unpack that tarball, both the `setup.py` file and the `PKG-INFO` file have an `mtime` of 0. `ctime` and `atime` are set properly.

This is clearly visible if you do an `ls -al` in the unpacked tarball directory. Or you can do `stat -c '%X %Y %Z' setup.py`.

This should repro with any `pyproject.toml` but if it doesn't, happy to upload mine.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `poetry/masonry/builders/sdist.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 import os
3 import re
4 import tarfile
5 
6 from collections import defaultdict
7 from copy import copy
8 from gzip import GzipFile
9 from io import BytesIO
10 from posixpath import join as pjoin
11 from pprint import pformat
12 
13 from poetry.utils._compat import Path
14 from poetry.utils._compat import encode
15 from poetry.utils._compat import to_str
16 
17 from ..utils.helpers import normalize_file_permissions
18 from ..utils.package_include import PackageInclude
19 from .builder import Builder
20 
21 
22 SETUP = """\
23 # -*- coding: utf-8 -*-
24 from setuptools import setup
25 
26 {before}
27 setup_kwargs = {{
28     'name': {name!r},
29     'version': {version!r},
30     'description': {description!r},
31     'long_description': {long_description!r},
32     'author': {author!r},
33     'author_email': {author_email!r},
34     'maintainer': {maintainer!r},
35     'maintainer_email': {maintainer_email!r},
36     'url': {url!r},
37     {extra}
38 }}
39 {after}
40 
41 setup(**setup_kwargs)
42 """
43 
44 
45 class SdistBuilder(Builder):
46 
47     format = "sdist"
48 
49     def build(self, target_dir=None):  # type: (Path) -> Path
50         self._io.write_line(" - Building <info>sdist</info>")
51         if target_dir is None:
52             target_dir = self._path / "dist"
53 
54         if not target_dir.exists():
55             target_dir.mkdir(parents=True)
56 
57         target = target_dir / "{}-{}.tar.gz".format(
58             self._package.pretty_name, self._meta.version
59         )
60         gz = GzipFile(target.as_posix(), mode="wb")
61         tar = tarfile.TarFile(
62             target.as_posix(), mode="w", fileobj=gz, format=tarfile.PAX_FORMAT
63         )
64 
65         try:
66             tar_dir = "{}-{}".format(self._package.pretty_name, self._meta.version)
67 
68             files_to_add = self.find_files_to_add(exclude_build=False)
69 
70             for relpath in files_to_add:
71                 path = self._path / relpath
72                 tar_info = tar.gettarinfo(
73                     str(path), arcname=pjoin(tar_dir, str(relpath))
74                 )
75                 tar_info = self.clean_tarinfo(tar_info)
76 
77                 if tar_info.isreg():
78                     with path.open("rb") as f:
79                         tar.addfile(tar_info, f)
80                 else:
81                     tar.addfile(tar_info)  # Symlinks & ?
82 
83             setup = self.build_setup()
84             tar_info = tarfile.TarInfo(pjoin(tar_dir, "setup.py"))
85             tar_info.size = len(setup)
86             tar.addfile(tar_info, BytesIO(setup))
87 
88             pkg_info = self.build_pkg_info()
89 
90             tar_info = tarfile.TarInfo(pjoin(tar_dir, "PKG-INFO"))
91             tar_info.size = len(pkg_info)
92             tar.addfile(tar_info, BytesIO(pkg_info))
93         finally:
94             tar.close()
95             gz.close()
96 
97         self._io.write_line(" - Built <comment>{}</comment>".format(target.name))
98 
99         return target
100 
101     def build_setup(self):  # type: () -> bytes
102         before, extra, after = [], [], []
103         package_dir = {}
104 
105         # If we have a build script, use it
106         if self._package.build:
107             after += [
108                 "from {} import *".format(self._package.build.split(".")[0]),
109                 "build(setup_kwargs)",
110             ]
111 
112         modules = []
113         packages = []
114         package_data = {}
115         for include in self._module.includes:
116             if include.formats and "sdist" not in include.formats:
117                 continue
118 
119             if isinstance(include, PackageInclude):
120                 if include.is_package():
121                     pkg_dir, _packages, _package_data = self.find_packages(include)
122 
123                     if pkg_dir is not None:
124                         package_dir[""] = os.path.relpath(pkg_dir, str(self._path))
125 
126                     packages += [p for p in _packages if p not in packages]
127                     package_data.update(_package_data)
128                 else:
129                     module = include.elements[0].relative_to(include.base).stem
130 
131                     if include.source is not None:
132                         package_dir[""] = str(include.base.relative_to(self._path))
133 
134                     if module not in modules:
135                         modules.append(module)
136             else:
137                 pass
138 
139         if package_dir:
140             before.append("package_dir = \\\n{}\n".format(pformat(package_dir)))
141             extra.append("'package_dir': package_dir,")
142 
143         if packages:
144             before.append("packages = \\\n{}\n".format(pformat(sorted(packages))))
145             extra.append("'packages': packages,")
146 
147         if package_data:
148             before.append("package_data = \\\n{}\n".format(pformat(package_data)))
149             extra.append("'package_data': package_data,")
150 
151         if modules:
152             before.append("modules = \\\n{}".format(pformat(modules)))
153             extra.append("'py_modules': modules,".format())
154 
155         dependencies, extras = self.convert_dependencies(
156             self._package, self._package.requires
157         )
158         if dependencies:
159             before.append(
160                 "install_requires = \\\n{}\n".format(pformat(sorted(dependencies)))
161             )
162             extra.append("'install_requires': install_requires,")
163 
164         if extras:
165             before.append("extras_require = \\\n{}\n".format(pformat(extras)))
166             extra.append("'extras_require': extras_require,")
167 
168         entry_points = self.convert_entry_points()
169         if entry_points:
170             before.append("entry_points = \\\n{}\n".format(pformat(entry_points)))
171             extra.append("'entry_points': entry_points,")
172 
173         if self._package.python_versions != "*":
174             python_requires = self._meta.requires_python
175 
176             extra.append("'python_requires': {!r},".format(python_requires))
177 
178         return encode(
179             SETUP.format(
180                 before="\n".join(before),
181                 name=to_str(self._meta.name),
182                 version=to_str(self._meta.version),
183                 description=to_str(self._meta.summary),
184                 long_description=to_str(self._meta.description),
185                 author=to_str(self._meta.author),
186                 author_email=to_str(self._meta.author_email),
187                 maintainer=to_str(self._meta.maintainer),
188                 maintainer_email=to_str(self._meta.maintainer_email),
189                 url=to_str(self._meta.home_page),
190                 extra="\n    ".join(extra),
191                 after="\n".join(after),
192             )
193         )
194 
195     def build_pkg_info(self):
196         return encode(self.get_metadata_content())
197 
198     def find_packages(self, include):
199         """
200         Discover subpackages and data.
201 
202         It also retrieves necessary files.
203         """
204         pkgdir = None
205         if include.source is not None:
206             pkgdir = str(include.base)
207 
208         base = str(include.elements[0].parent)
209 
210         pkg_name = include.package
211         pkg_data = defaultdict(list)
212         # Undocumented distutils feature:
213         # the empty string matches all package names
214         pkg_data[""].append("*")
215         packages = [pkg_name]
216         subpkg_paths = set()
217 
218         def find_nearest_pkg(rel_path):
219             parts = rel_path.split(os.sep)
220             for i in reversed(range(1, len(parts))):
221                 ancestor = "/".join(parts[:i])
222                 if ancestor in subpkg_paths:
223                     pkg = ".".join([pkg_name] + parts[:i])
224                     return pkg, "/".join(parts[i:])
225 
226             # Relative to the top-level package
227             return pkg_name, Path(rel_path).as_posix()
228 
229         for path, dirnames, filenames in os.walk(str(base), topdown=True):
230             if os.path.basename(path) == "__pycache__":
231                 continue
232 
233             from_top_level = os.path.relpath(path, base)
234             if from_top_level == ".":
235                 continue
236 
237             is_subpkg = "__init__.py" in filenames
238             if is_subpkg:
239                 subpkg_paths.add(from_top_level)
240                 parts = from_top_level.split(os.sep)
241                 packages.append(".".join([pkg_name] + parts))
242             else:
243                 pkg, from_nearest_pkg = find_nearest_pkg(from_top_level)
244 
245                 data_elements = [
246                     f.relative_to(self._path)
247                     for f in Path(path).glob("*")
248                     if not f.is_dir()
249                 ]
250 
251                 data = [e for e in data_elements if not self.is_excluded(e)]
252                 if not data:
253                     continue
254 
255                 if len(data) == len(data_elements):
256                     pkg_data[pkg].append(pjoin(from_nearest_pkg, "*"))
257                 else:
258                     for d in data:
259                         if d.is_dir():
260                             continue
261 
262                         pkg_data[pkg] += [pjoin(from_nearest_pkg, d.name) for d in data]
263 
264         # Sort values in pkg_data
265         pkg_data = {k: sorted(v) for (k, v) in pkg_data.items() if v}
266 
267         return pkgdir, sorted(packages), pkg_data
268 
269     @classmethod
270     def convert_dependencies(cls, package, dependencies):
271         main = []
272         extras = defaultdict(list)
273         req_regex = re.compile(r"^(.+) \((.+)\)$")
274 
275         for dependency in dependencies:
276             if dependency.is_optional():
277                 for extra_name, reqs in package.extras.items():
278                     for req in reqs:
279                         if req.name == dependency.name:
280                             requirement = to_str(
281                                 dependency.to_pep_508(with_extras=False)
282                             )
283                             if ";" in requirement:
284                                 requirement, conditions = requirement.split(";")
285 
286                                 requirement = requirement.strip()
287                                 if req_regex.match(requirement):
288                                     requirement = req_regex.sub(
289                                         "\\1\\2", requirement.strip()
290                                     )
291 
292                                 extras[extra_name + ":" + conditions.strip()].append(
293                                     requirement
294                                 )
295 
296                                 continue
297 
298                             requirement = requirement.strip()
299                             if req_regex.match(requirement):
300                                 requirement = req_regex.sub(
301                                     "\\1\\2", requirement.strip()
302                                 )
303                             extras[extra_name].append(requirement)
304                 continue
305 
306             requirement = to_str(dependency.to_pep_508())
307             if ";" in requirement:
308                 requirement, conditions = requirement.split(";")
309 
310                 requirement = requirement.strip()
311                 if req_regex.match(requirement):
312                     requirement = req_regex.sub("\\1\\2", requirement.strip())
313 
314                 extras[":" + conditions.strip()].append(requirement)
315 
316                 continue
317 
318             requirement = requirement.strip()
319             if req_regex.match(requirement):
320                 requirement = req_regex.sub("\\1\\2", requirement.strip())
321 
322             main.append(requirement)
323 
324         return main, dict(extras)
325 
326     @classmethod
327     def clean_tarinfo(cls, tar_info):
328         """
329         Clean metadata from a TarInfo object to make it more reproducible.
330 
331             - Set uid & gid to 0
332             - Set uname and gname to ""
333             - Normalise permissions to 644 or 755
334             - Set mtime if not None
335         """
336         ti = copy(tar_info)
337         ti.uid = 0
338         ti.gid = 0
339         ti.uname = ""
340         ti.gname = ""
341         ti.mode = normalize_file_permissions(ti.mode)
342 
343         return ti
344
```
--- 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/poetry/masonry/builders/sdist.py b/poetry/masonry/builders/sdist.py
--- a/poetry/masonry/builders/sdist.py
+++ b/poetry/masonry/builders/sdist.py
@@ -2,6 +2,7 @@
 import os
 import re
 import tarfile
+import time
 
 from collections import defaultdict
 from copy import copy
@@ -83,12 +84,14 @@
             setup = self.build_setup()
             tar_info = tarfile.TarInfo(pjoin(tar_dir, "setup.py"))
             tar_info.size = len(setup)
+            tar_info.mtime = time.time()
             tar.addfile(tar_info, BytesIO(setup))
 
             pkg_info = self.build_pkg_info()
 
             tar_info = tarfile.TarInfo(pjoin(tar_dir, "PKG-INFO"))
             tar_info.size = len(pkg_info)
+            tar_info.mtime = time.time()
             tar.addfile(tar_info, BytesIO(pkg_info))
         finally:
             tar.close()

{"golden_diff": "diff --git a/poetry/masonry/builders/sdist.py b/poetry/masonry/builders/sdist.py\n--- a/poetry/masonry/builders/sdist.py\n+++ b/poetry/masonry/builders/sdist.py\n@@ -2,6 +2,7 @@\n import os\n import re\n import tarfile\n+import time\n \n from collections import defaultdict\n from copy import copy\n@@ -83,12 +84,14 @@\n             setup = self.build_setup()\n             tar_info = tarfile.TarInfo(pjoin(tar_dir, \"setup.py\"))\n             tar_info.size = len(setup)\n+            tar_info.mtime = time.time()\n             tar.addfile(tar_info, BytesIO(setup))\n \n             pkg_info = self.build_pkg_info()\n \n             tar_info = tarfile.TarInfo(pjoin(tar_dir, \"PKG-INFO\"))\n             tar_info.size = len(pkg_info)\n+            tar_info.mtime = time.time()\n             tar.addfile(tar_info, BytesIO(pkg_info))\n         finally:\n             tar.close()\n", "issue": "mtime set to 0 on setup.py and PKG-INFO in sdist package\n<!--\r\n  Hi there! Thank you for discovering and submitting an issue.\r\n\r\n  Before you submit this; let's make sure of a few things.\r\n  Please make sure the following boxes are ticked if they are correct.\r\n  If not, please try and fulfill these first.\r\n-->\r\n\r\n<!-- Checked checkbox should look like this: [x] -->\r\n- [x] I am on the [latest](https://github.com/sdispater/poetry/releases/latest) Poetry version.\r\n- [x] I have searched the [issues](https://github.com/sdispater/poetry/issues) of this repo and believe that this is not a duplicate.\r\n- [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option).\r\n\r\n<!--\r\n  Once those are done, if you're able to fill in the following list with your information,\r\n  it'd be very helpful to whoever handles the issue.\r\n-->\r\n\r\n- **OS version and name**: Ubuntu 18.04.1 LTS\r\n- **Poetry version**: 0.12.10\r\n- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**: <!-- Gist Link Here -->\r\n\r\n## Issue\r\n<!-- Now feel free to write your issue, but please be descriptive! Thanks again \ud83d\ude4c \u2764\ufe0f -->\r\n`poetry build` creates an `sdist` tarball. If you unpack that tarball, both the `setup.py` file and the `PKG-INFO` file have an `mtime` of 0. `ctime` and `atime` are set properly.\r\n\r\nThis is clearly visible if you do an `ls -al` in the unpacked tarball directory. Or you can do `stat -c '%X %Y %Z' setup.py`.\r\n\r\nThis should repro with any `pyproject.toml` but if it doesn't, happy to upload mine.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport os\nimport re\nimport tarfile\n\nfrom collections import defaultdict\nfrom copy import copy\nfrom gzip import GzipFile\nfrom io import BytesIO\nfrom posixpath import join as pjoin\nfrom pprint import pformat\n\nfrom poetry.utils._compat import Path\nfrom poetry.utils._compat import encode\nfrom poetry.utils._compat import to_str\n\nfrom ..utils.helpers import normalize_file_permissions\nfrom ..utils.package_include import PackageInclude\nfrom .builder import Builder\n\n\nSETUP = \"\"\"\\\n# -*- coding: utf-8 -*-\nfrom setuptools import setup\n\n{before}\nsetup_kwargs = {{\n    'name': {name!r},\n    'version': {version!r},\n    'description': {description!r},\n    'long_description': {long_description!r},\n    'author': {author!r},\n    'author_email': {author_email!r},\n    'maintainer': {maintainer!r},\n    'maintainer_email': {maintainer_email!r},\n    'url': {url!r},\n    {extra}\n}}\n{after}\n\nsetup(**setup_kwargs)\n\"\"\"\n\n\nclass SdistBuilder(Builder):\n\n    format = \"sdist\"\n\n    def build(self, target_dir=None):  # type: (Path) -> Path\n        self._io.write_line(\" - Building <info>sdist</info>\")\n        if target_dir is None:\n            target_dir = self._path / \"dist\"\n\n        if not target_dir.exists():\n            target_dir.mkdir(parents=True)\n\n        target = target_dir / \"{}-{}.tar.gz\".format(\n            self._package.pretty_name, self._meta.version\n        )\n        gz = GzipFile(target.as_posix(), mode=\"wb\")\n        tar = tarfile.TarFile(\n            target.as_posix(), mode=\"w\", fileobj=gz, format=tarfile.PAX_FORMAT\n        )\n\n        try:\n            tar_dir = \"{}-{}\".format(self._package.pretty_name, self._meta.version)\n\n            files_to_add = self.find_files_to_add(exclude_build=False)\n\n            for relpath in files_to_add:\n                path = self._path / relpath\n                tar_info = tar.gettarinfo(\n                    str(path), arcname=pjoin(tar_dir, str(relpath))\n                )\n                tar_info = self.clean_tarinfo(tar_info)\n\n                if tar_info.isreg():\n                    with path.open(\"rb\") as f:\n                        tar.addfile(tar_info, f)\n                else:\n                    tar.addfile(tar_info)  # Symlinks & ?\n\n            setup = self.build_setup()\n            tar_info = tarfile.TarInfo(pjoin(tar_dir, \"setup.py\"))\n            tar_info.size = len(setup)\n            tar.addfile(tar_info, BytesIO(setup))\n\n            pkg_info = self.build_pkg_info()\n\n            tar_info = tarfile.TarInfo(pjoin(tar_dir, \"PKG-INFO\"))\n            tar_info.size = len(pkg_info)\n            tar.addfile(tar_info, BytesIO(pkg_info))\n        finally:\n            tar.close()\n            gz.close()\n\n        self._io.write_line(\" - Built <comment>{}</comment>\".format(target.name))\n\n        return target\n\n    def build_setup(self):  # type: () -> bytes\n        before, extra, after = [], [], []\n        package_dir = {}\n\n        # If we have a build script, use it\n        if self._package.build:\n            after += [\n                \"from {} import *\".format(self._package.build.split(\".\")[0]),\n                \"build(setup_kwargs)\",\n            ]\n\n        modules = []\n        packages = []\n        package_data = {}\n        for include in self._module.includes:\n            if include.formats and \"sdist\" not in include.formats:\n                continue\n\n            if isinstance(include, PackageInclude):\n                if include.is_package():\n                    pkg_dir, _packages, _package_data = self.find_packages(include)\n\n                    if pkg_dir is not None:\n                        package_dir[\"\"] = os.path.relpath(pkg_dir, str(self._path))\n\n                    packages += [p for p in _packages if p not in packages]\n                    package_data.update(_package_data)\n                else:\n                    module = include.elements[0].relative_to(include.base).stem\n\n                    if include.source is not None:\n                        package_dir[\"\"] = str(include.base.relative_to(self._path))\n\n                    if module not in modules:\n                        modules.append(module)\n            else:\n                pass\n\n        if package_dir:\n            before.append(\"package_dir = \\\\\\n{}\\n\".format(pformat(package_dir)))\n            extra.append(\"'package_dir': package_dir,\")\n\n        if packages:\n            before.append(\"packages = \\\\\\n{}\\n\".format(pformat(sorted(packages))))\n            extra.append(\"'packages': packages,\")\n\n        if package_data:\n            before.append(\"package_data = \\\\\\n{}\\n\".format(pformat(package_data)))\n            extra.append(\"'package_data': package_data,\")\n\n        if modules:\n            before.append(\"modules = \\\\\\n{}\".format(pformat(modules)))\n            extra.append(\"'py_modules': modules,\".format())\n\n        dependencies, extras = self.convert_dependencies(\n            self._package, self._package.requires\n        )\n        if dependencies:\n            before.append(\n                \"install_requires = \\\\\\n{}\\n\".format(pformat(sorted(dependencies)))\n            )\n            extra.append(\"'install_requires': install_requires,\")\n\n        if extras:\n            before.append(\"extras_require = \\\\\\n{}\\n\".format(pformat(extras)))\n            extra.append(\"'extras_require': extras_require,\")\n\n        entry_points = self.convert_entry_points()\n        if entry_points:\n            before.append(\"entry_points = \\\\\\n{}\\n\".format(pformat(entry_points)))\n            extra.append(\"'entry_points': entry_points,\")\n\n        if self._package.python_versions != \"*\":\n            python_requires = self._meta.requires_python\n\n            extra.append(\"'python_requires': {!r},\".format(python_requires))\n\n        return encode(\n            SETUP.format(\n                before=\"\\n\".join(before),\n                name=to_str(self._meta.name),\n                version=to_str(self._meta.version),\n                description=to_str(self._meta.summary),\n                long_description=to_str(self._meta.description),\n                author=to_str(self._meta.author),\n                author_email=to_str(self._meta.author_email),\n                maintainer=to_str(self._meta.maintainer),\n                maintainer_email=to_str(self._meta.maintainer_email),\n                url=to_str(self._meta.home_page),\n                extra=\"\\n    \".join(extra),\n                after=\"\\n\".join(after),\n            )\n        )\n\n    def build_pkg_info(self):\n        return encode(self.get_metadata_content())\n\n    def find_packages(self, include):\n        \"\"\"\n        Discover subpackages and data.\n\n        It also retrieves necessary files.\n        \"\"\"\n        pkgdir = None\n        if include.source is not None:\n            pkgdir = str(include.base)\n\n        base = str(include.elements[0].parent)\n\n        pkg_name = include.package\n        pkg_data = defaultdict(list)\n        # Undocumented distutils feature:\n        # the empty string matches all package names\n        pkg_data[\"\"].append(\"*\")\n        packages = [pkg_name]\n        subpkg_paths = set()\n\n        def find_nearest_pkg(rel_path):\n            parts = rel_path.split(os.sep)\n            for i in reversed(range(1, len(parts))):\n                ancestor = \"/\".join(parts[:i])\n                if ancestor in subpkg_paths:\n                    pkg = \".\".join([pkg_name] + parts[:i])\n                    return pkg, \"/\".join(parts[i:])\n\n            # Relative to the top-level package\n            return pkg_name, Path(rel_path).as_posix()\n\n        for path, dirnames, filenames in os.walk(str(base), topdown=True):\n            if os.path.basename(path) == \"__pycache__\":\n                continue\n\n            from_top_level = os.path.relpath(path, base)\n            if from_top_level == \".\":\n                continue\n\n            is_subpkg = \"__init__.py\" in filenames\n            if is_subpkg:\n                subpkg_paths.add(from_top_level)\n                parts = from_top_level.split(os.sep)\n                packages.append(\".\".join([pkg_name] + parts))\n            else:\n                pkg, from_nearest_pkg = find_nearest_pkg(from_top_level)\n\n                data_elements = [\n                    f.relative_to(self._path)\n                    for f in Path(path).glob(\"*\")\n                    if not f.is_dir()\n                ]\n\n                data = [e for e in data_elements if not self.is_excluded(e)]\n                if not data:\n                    continue\n\n                if len(data) == len(data_elements):\n                    pkg_data[pkg].append(pjoin(from_nearest_pkg, \"*\"))\n                else:\n                    for d in data:\n                        if d.is_dir():\n                            continue\n\n                        pkg_data[pkg] += [pjoin(from_nearest_pkg, d.name) for d in data]\n\n        # Sort values in pkg_data\n        pkg_data = {k: sorted(v) for (k, v) in pkg_data.items() if v}\n\n        return pkgdir, sorted(packages), pkg_data\n\n    @classmethod\n    def convert_dependencies(cls, package, dependencies):\n        main = []\n        extras = defaultdict(list)\n        req_regex = re.compile(r\"^(.+) \\((.+)\\)$\")\n\n        for dependency in dependencies:\n            if dependency.is_optional():\n                for extra_name, reqs in package.extras.items():\n                    for req in reqs:\n                        if req.name == dependency.name:\n                            requirement = to_str(\n                                dependency.to_pep_508(with_extras=False)\n                            )\n                            if \";\" in requirement:\n                                requirement, conditions = requirement.split(\";\")\n\n                                requirement = requirement.strip()\n                                if req_regex.match(requirement):\n                                    requirement = req_regex.sub(\n                                        \"\\\\1\\\\2\", requirement.strip()\n                                    )\n\n                                extras[extra_name + \":\" + conditions.strip()].append(\n                                    requirement\n                                )\n\n                                continue\n\n                            requirement = requirement.strip()\n                            if req_regex.match(requirement):\n                                requirement = req_regex.sub(\n                                    \"\\\\1\\\\2\", requirement.strip()\n                                )\n                            extras[extra_name].append(requirement)\n                continue\n\n            requirement = to_str(dependency.to_pep_508())\n            if \";\" in requirement:\n                requirement, conditions = requirement.split(\";\")\n\n                requirement = requirement.strip()\n                if req_regex.match(requirement):\n                    requirement = req_regex.sub(\"\\\\1\\\\2\", requirement.strip())\n\n                extras[\":\" + conditions.strip()].append(requirement)\n\n                continue\n\n            requirement = requirement.strip()\n            if req_regex.match(requirement):\n                requirement = req_regex.sub(\"\\\\1\\\\2\", requirement.strip())\n\n            main.append(requirement)\n\n        return main, dict(extras)\n\n    @classmethod\n    def clean_tarinfo(cls, tar_info):\n        \"\"\"\n        Clean metadata from a TarInfo object to make it more reproducible.\n\n            - Set uid & gid to 0\n            - Set uname and gname to \"\"\n            - Normalise permissions to 644 or 755\n            - Set mtime if not None\n        \"\"\"\n        ti = copy(tar_info)\n        ti.uid = 0\n        ti.gid = 0\n        ti.uname = \"\"\n        ti.gname = \"\"\n        ti.mode = normalize_file_permissions(ti.mode)\n\n        return ti\n", "path": "poetry/masonry/builders/sdist.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport os\nimport re\nimport tarfile\nimport time\n\nfrom collections import defaultdict\nfrom copy import copy\nfrom gzip import GzipFile\nfrom io import BytesIO\nfrom posixpath import join as pjoin\nfrom pprint import pformat\n\nfrom poetry.utils._compat import Path\nfrom poetry.utils._compat import encode\nfrom poetry.utils._compat import to_str\n\nfrom ..utils.helpers import normalize_file_permissions\nfrom ..utils.package_include import PackageInclude\nfrom .builder import Builder\n\n\nSETUP = \"\"\"\\\n# -*- coding: utf-8 -*-\nfrom setuptools import setup\n\n{before}\nsetup_kwargs = {{\n    'name': {name!r},\n    'version': {version!r},\n    'description': {description!r},\n    'long_description': {long_description!r},\n    'author': {author!r},\n    'author_email': {author_email!r},\n    'maintainer': {maintainer!r},\n    'maintainer_email': {maintainer_email!r},\n    'url': {url!r},\n    {extra}\n}}\n{after}\n\nsetup(**setup_kwargs)\n\"\"\"\n\n\nclass SdistBuilder(Builder):\n\n    format = \"sdist\"\n\n    def build(self, target_dir=None):  # type: (Path) -> Path\n        self._io.write_line(\" - Building <info>sdist</info>\")\n        if target_dir is None:\n            target_dir = self._path / \"dist\"\n\n        if not target_dir.exists():\n            target_dir.mkdir(parents=True)\n\n        target = target_dir / \"{}-{}.tar.gz\".format(\n            self._package.pretty_name, self._meta.version\n        )\n        gz = GzipFile(target.as_posix(), mode=\"wb\")\n        tar = tarfile.TarFile(\n            target.as_posix(), mode=\"w\", fileobj=gz, format=tarfile.PAX_FORMAT\n        )\n\n        try:\n            tar_dir = \"{}-{}\".format(self._package.pretty_name, self._meta.version)\n\n            files_to_add = self.find_files_to_add(exclude_build=False)\n\n            for relpath in files_to_add:\n                path = self._path / relpath\n                tar_info = tar.gettarinfo(\n                    str(path), arcname=pjoin(tar_dir, str(relpath))\n                )\n                tar_info = self.clean_tarinfo(tar_info)\n\n                if tar_info.isreg():\n                    with path.open(\"rb\") as f:\n                        tar.addfile(tar_info, f)\n                else:\n                    tar.addfile(tar_info)  # Symlinks & ?\n\n            setup = self.build_setup()\n            tar_info = tarfile.TarInfo(pjoin(tar_dir, \"setup.py\"))\n            tar_info.size = len(setup)\n            tar_info.mtime = time.time()\n            tar.addfile(tar_info, BytesIO(setup))\n\n            pkg_info = self.build_pkg_info()\n\n            tar_info = tarfile.TarInfo(pjoin(tar_dir, \"PKG-INFO\"))\n            tar_info.size = len(pkg_info)\n            tar_info.mtime = time.time()\n            tar.addfile(tar_info, BytesIO(pkg_info))\n        finally:\n            tar.close()\n            gz.close()\n\n        self._io.write_line(\" - Built <comment>{}</comment>\".format(target.name))\n\n        return target\n\n    def build_setup(self):  # type: () -> bytes\n        before, extra, after = [], [], []\n        package_dir = {}\n\n        # If we have a build script, use it\n        if self._package.build:\n            after += [\n                \"from {} import *\".format(self._package.build.split(\".\")[0]),\n                \"build(setup_kwargs)\",\n            ]\n\n        modules = []\n        packages = []\n        package_data = {}\n        for include in self._module.includes:\n            if include.formats and \"sdist\" not in include.formats:\n                continue\n\n            if isinstance(include, PackageInclude):\n                if include.is_package():\n                    pkg_dir, _packages, _package_data = self.find_packages(include)\n\n                    if pkg_dir is not None:\n                        package_dir[\"\"] = os.path.relpath(pkg_dir, str(self._path))\n\n                    packages += [p for p in _packages if p not in packages]\n                    package_data.update(_package_data)\n                else:\n                    module = include.elements[0].relative_to(include.base).stem\n\n                    if include.source is not None:\n                        package_dir[\"\"] = str(include.base.relative_to(self._path))\n\n                    if module not in modules:\n                        modules.append(module)\n            else:\n                pass\n\n        if package_dir:\n            before.append(\"package_dir = \\\\\\n{}\\n\".format(pformat(package_dir)))\n            extra.append(\"'package_dir': package_dir,\")\n\n        if packages:\n            before.append(\"packages = \\\\\\n{}\\n\".format(pformat(sorted(packages))))\n            extra.append(\"'packages': packages,\")\n\n        if package_data:\n            before.append(\"package_data = \\\\\\n{}\\n\".format(pformat(package_data)))\n            extra.append(\"'package_data': package_data,\")\n\n        if modules:\n            before.append(\"modules = \\\\\\n{}\".format(pformat(modules)))\n            extra.append(\"'py_modules': modules,\".format())\n\n        dependencies, extras = self.convert_dependencies(\n            self._package, self._package.requires\n        )\n        if dependencies:\n            before.append(\n                \"install_requires = \\\\\\n{}\\n\".format(pformat(sorted(dependencies)))\n            )\n            extra.append(\"'install_requires': install_requires,\")\n\n        if extras:\n            before.append(\"extras_require = \\\\\\n{}\\n\".format(pformat(extras)))\n            extra.append(\"'extras_require': extras_require,\")\n\n        entry_points = self.convert_entry_points()\n        if entry_points:\n            before.append(\"entry_points = \\\\\\n{}\\n\".format(pformat(entry_points)))\n            extra.append(\"'entry_points': entry_points,\")\n\n        if self._package.python_versions != \"*\":\n            python_requires = self._meta.requires_python\n\n            extra.append(\"'python_requires': {!r},\".format(python_requires))\n\n        return encode(\n            SETUP.format(\n                before=\"\\n\".join(before),\n                name=to_str(self._meta.name),\n                version=to_str(self._meta.version),\n                description=to_str(self._meta.summary),\n                long_description=to_str(self._meta.description),\n                author=to_str(self._meta.author),\n                author_email=to_str(self._meta.author_email),\n                maintainer=to_str(self._meta.maintainer),\n                maintainer_email=to_str(self._meta.maintainer_email),\n                url=to_str(self._meta.home_page),\n                extra=\"\\n    \".join(extra),\n                after=\"\\n\".join(after),\n            )\n        )\n\n    def build_pkg_info(self):\n        return encode(self.get_metadata_content())\n\n    def find_packages(self, include):\n        \"\"\"\n        Discover subpackages and data.\n\n        It also retrieves necessary files.\n        \"\"\"\n        pkgdir = None\n        if include.source is not None:\n            pkgdir = str(include.base)\n\n        base = str(include.elements[0].parent)\n\n        pkg_name = include.package\n        pkg_data = defaultdict(list)\n        # Undocumented distutils feature:\n        # the empty string matches all package names\n        pkg_data[\"\"].append(\"*\")\n        packages = [pkg_name]\n        subpkg_paths = set()\n\n        def find_nearest_pkg(rel_path):\n            parts = rel_path.split(os.sep)\n            for i in reversed(range(1, len(parts))):\n                ancestor = \"/\".join(parts[:i])\n                if ancestor in subpkg_paths:\n                    pkg = \".\".join([pkg_name] + parts[:i])\n                    return pkg, \"/\".join(parts[i:])\n\n            # Relative to the top-level package\n            return pkg_name, Path(rel_path).as_posix()\n\n        for path, dirnames, filenames in os.walk(str(base), topdown=True):\n            if os.path.basename(path) == \"__pycache__\":\n                continue\n\n            from_top_level = os.path.relpath(path, base)\n            if from_top_level == \".\":\n                continue\n\n            is_subpkg = \"__init__.py\" in filenames\n            if is_subpkg:\n                subpkg_paths.add(from_top_level)\n                parts = from_top_level.split(os.sep)\n                packages.append(\".\".join([pkg_name] + parts))\n            else:\n                pkg, from_nearest_pkg = find_nearest_pkg(from_top_level)\n\n                data_elements = [\n                    f.relative_to(self._path)\n                    for f in Path(path).glob(\"*\")\n                    if not f.is_dir()\n                ]\n\n                data = [e for e in data_elements if not self.is_excluded(e)]\n                if not data:\n                    continue\n\n                if len(data) == len(data_elements):\n                    pkg_data[pkg].append(pjoin(from_nearest_pkg, \"*\"))\n                else:\n                    for d in data:\n                        if d.is_dir():\n                            continue\n\n                        pkg_data[pkg] += [pjoin(from_nearest_pkg, d.name) for d in data]\n\n        # Sort values in pkg_data\n        pkg_data = {k: sorted(v) for (k, v) in pkg_data.items() if v}\n\n        return pkgdir, sorted(packages), pkg_data\n\n    @classmethod\n    def convert_dependencies(cls, package, dependencies):\n        main = []\n        extras = defaultdict(list)\n        req_regex = re.compile(r\"^(.+) \\((.+)\\)$\")\n\n        for dependency in dependencies:\n            if dependency.is_optional():\n                for extra_name, reqs in package.extras.items():\n                    for req in reqs:\n                        if req.name == dependency.name:\n                            requirement = to_str(\n                                dependency.to_pep_508(with_extras=False)\n                            )\n                            if \";\" in requirement:\n                                requirement, conditions = requirement.split(\";\")\n\n                                requirement = requirement.strip()\n                                if req_regex.match(requirement):\n                                    requirement = req_regex.sub(\n                                        \"\\\\1\\\\2\", requirement.strip()\n                                    )\n\n                                extras[extra_name + \":\" + conditions.strip()].append(\n                                    requirement\n                                )\n\n                                continue\n\n                            requirement = requirement.strip()\n                            if req_regex.match(requirement):\n                                requirement = req_regex.sub(\n                                    \"\\\\1\\\\2\", requirement.strip()\n                                )\n                            extras[extra_name].append(requirement)\n                continue\n\n            requirement = to_str(dependency.to_pep_508())\n            if \";\" in requirement:\n                requirement, conditions = requirement.split(\";\")\n\n                requirement = requirement.strip()\n                if req_regex.match(requirement):\n                    requirement = req_regex.sub(\"\\\\1\\\\2\", requirement.strip())\n\n                extras[\":\" + conditions.strip()].append(requirement)\n\n                continue\n\n            requirement = requirement.strip()\n            if req_regex.match(requirement):\n                requirement = req_regex.sub(\"\\\\1\\\\2\", requirement.strip())\n\n            main.append(requirement)\n\n        return main, dict(extras)\n\n    @classmethod\n    def clean_tarinfo(cls, tar_info):\n        \"\"\"\n        Clean metadata from a TarInfo object to make it more reproducible.\n\n            - Set uid & gid to 0\n            - Set uname and gname to \"\"\n            - Normalise permissions to 644 or 755\n            - Set mtime if not None\n        \"\"\"\n        ti = copy(tar_info)\n        ti.uid = 0\n        ti.gid = 0\n        ti.uname = \"\"\n        ti.gname = \"\"\n        ti.mode = normalize_file_permissions(ti.mode)\n\n        return ti\n", "path": "poetry/masonry/builders/sdist.py"}]}