We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
pyproject.toml should be included in sdist by default
An issue came up at work recently where installing [python-daemon](https://pagure.io/python-daemon) with `pip` was hitting the `easy_install` path. I assumed it was because `python-daemon` didn't have a `pyproject.toml`, but it turns out they do - it's just not included in the `Manifest.in`, so it didn't get included in the `sdist`. To verify this I created a super basic example project and it does seem that the default is to exclude `pyproject.toml`.

Given that `pyproject.toml` is one of the most important files to have when executing a build, it should be included in the sdist unless explicitly excluded.

--- 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/command/sdist.py`
Content:
```
1 from distutils import log
2 import distutils.command.sdist as orig
3 import os
4 import sys
5 import io
6 import contextlib
7 
8 from setuptools.extern import six, ordered_set
9 
10 from .py36compat import sdist_add_defaults
11 
12 import pkg_resources
13 
14 _default_revctrl = list
15 
16 
17 def walk_revctrl(dirname=''):
18     """Find all files under revision control"""
19     for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):
20         for item in ep.load()(dirname):
21             yield item
22 
23 
24 class sdist(sdist_add_defaults, orig.sdist):
25     """Smart sdist that finds anything supported by revision control"""
26 
27     user_options = [
28         ('formats=', None,
29          "formats for source distribution (comma-separated list)"),
30         ('keep-temp', 'k',
31          "keep the distribution tree around after creating " +
32          "archive file(s)"),
33         ('dist-dir=', 'd',
34          "directory to put the source distribution archive(s) in "
35          "[default: dist]"),
36     ]
37 
38     negative_opt = {}
39 
40     README_EXTENSIONS = ['', '.rst', '.txt', '.md']
41     READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS)
42 
43     def run(self):
44         self.run_command('egg_info')
45         ei_cmd = self.get_finalized_command('egg_info')
46         self.filelist = ei_cmd.filelist
47         self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt'))
48         self.check_readme()
49 
50         # Run sub commands
51         for cmd_name in self.get_sub_commands():
52             self.run_command(cmd_name)
53 
54         self.make_distribution()
55 
56         dist_files = getattr(self.distribution, 'dist_files', [])
57         for file in self.archive_files:
58             data = ('sdist', '', file)
59             if data not in dist_files:
60                 dist_files.append(data)
61 
62     def initialize_options(self):
63         orig.sdist.initialize_options(self)
64 
65         self._default_to_gztar()
66 
67     def _default_to_gztar(self):
68         # only needed on Python prior to 3.6.
69         if sys.version_info >= (3, 6, 0, 'beta', 1):
70             return
71         self.formats = ['gztar']
72 
73     def make_distribution(self):
74         """
75         Workaround for #516
76         """
77         with self._remove_os_link():
78             orig.sdist.make_distribution(self)
79 
80     @staticmethod
81     @contextlib.contextmanager
82     def _remove_os_link():
83         """
84         In a context, remove and restore os.link if it exists
85         """
86 
87         class NoValue:
88             pass
89 
90         orig_val = getattr(os, 'link', NoValue)
91         try:
92             del os.link
93         except Exception:
94             pass
95         try:
96             yield
97         finally:
98             if orig_val is not NoValue:
99                 setattr(os, 'link', orig_val)
100 
101     def __read_template_hack(self):
102         # This grody hack closes the template file (MANIFEST.in) if an
103         #  exception occurs during read_template.
104         # Doing so prevents an error when easy_install attempts to delete the
105         #  file.
106         try:
107             orig.sdist.read_template(self)
108         except Exception:
109             _, _, tb = sys.exc_info()
110             tb.tb_next.tb_frame.f_locals['template'].close()
111             raise
112 
113     # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle
114     #  has been fixed, so only override the method if we're using an earlier
115     #  Python.
116     has_leaky_handle = (
117         sys.version_info < (2, 7, 2)
118         or (3, 0) <= sys.version_info < (3, 1, 4)
119         or (3, 2) <= sys.version_info < (3, 2, 1)
120     )
121     if has_leaky_handle:
122         read_template = __read_template_hack
123 
124     def _add_defaults_python(self):
125         """getting python files"""
126         if self.distribution.has_pure_modules():
127             build_py = self.get_finalized_command('build_py')
128             self.filelist.extend(build_py.get_source_files())
129             self._add_data_files(self._safe_data_files(build_py))
130 
131     def _safe_data_files(self, build_py):
132         """
133         Extracting data_files from build_py is known to cause
134         infinite recursion errors when `include_package_data`
135         is enabled, so suppress it in that case.
136         """
137         if self.distribution.include_package_data:
138             return ()
139         return build_py.data_files
140 
141     def _add_data_files(self, data_files):
142         """
143         Add data files as found in build_py.data_files.
144         """
145         self.filelist.extend(
146             os.path.join(src_dir, name)
147             for _, src_dir, _, filenames in data_files
148             for name in filenames
149         )
150 
151     def _add_defaults_data_files(self):
152         try:
153             if six.PY2:
154                 sdist_add_defaults._add_defaults_data_files(self)
155             else:
156                 super()._add_defaults_data_files()
157         except TypeError:
158             log.warn("data_files contains unexpected objects")
159 
160     def check_readme(self):
161         for f in self.READMES:
162             if os.path.exists(f):
163                 return
164         else:
165             self.warn(
166                 "standard file not found: should have one of " +
167                 ', '.join(self.READMES)
168             )
169 
170     def make_release_tree(self, base_dir, files):
171         orig.sdist.make_release_tree(self, base_dir, files)
172 
173         # Save any egg_info command line options used to create this sdist
174         dest = os.path.join(base_dir, 'setup.cfg')
175         if hasattr(os, 'link') and os.path.exists(dest):
176             # unlink and re-copy, since it might be hard-linked, and
177             # we don't want to change the source version
178             os.unlink(dest)
179             self.copy_file('setup.cfg', dest)
180 
181         self.get_finalized_command('egg_info').save_version_info(dest)
182 
183     def _manifest_is_not_generated(self):
184         # check for special comment used in 2.7.1 and higher
185         if not os.path.isfile(self.manifest):
186             return False
187 
188         with io.open(self.manifest, 'rb') as fp:
189             first_line = fp.readline()
190         return (first_line !=
191                 '# file GENERATED by distutils, do NOT edit\n'.encode())
192 
193     def read_manifest(self):
194         """Read the manifest file (named by 'self.manifest') and use it to
195         fill in 'self.filelist', the list of files to include in the source
196         distribution.
197         """
198         log.info("reading manifest file '%s'", self.manifest)
199         manifest = open(self.manifest, 'rb')
200         for line in manifest:
201             # The manifest must contain UTF-8. See #303.
202             if six.PY3:
203                 try:
204                     line = line.decode('UTF-8')
205                 except UnicodeDecodeError:
206                     log.warn("%r not UTF-8 decodable -- skipping" % line)
207                     continue
208             # ignore comments and blank lines
209             line = line.strip()
210             if line.startswith('#') or not line:
211                 continue
212             self.filelist.append(line)
213         manifest.close()
214 
215     def check_license(self):
216         """Checks if license_file' or 'license_files' is configured and adds any
217         valid paths to 'self.filelist'.
218         """
219 
220         files = ordered_set.OrderedSet()
221 
222         opts = self.distribution.get_option_dict('metadata')
223 
224         # ignore the source of the value
225         _, license_file = opts.get('license_file', (None, None))
226 
227         if license_file is None:
228             log.debug("'license_file' option was not specified")
229         else:
230             files.add(license_file)
231 
232         try:
233             files.update(self.distribution.metadata.license_files)
234         except TypeError:
235             log.warn("warning: 'license_files' option is malformed")
236 
237         for f in files:
238             if not os.path.exists(f):
239                 log.warn(
240                     "warning: Failed to find the configured license file '%s'",
241                     f)
242                 files.remove(f)
243 
244         self.filelist.extend(files)
245
```
--- 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/command/sdist.py b/setuptools/command/sdist.py
--- a/setuptools/command/sdist.py
+++ b/setuptools/command/sdist.py
@@ -121,6 +121,14 @@
     if has_leaky_handle:
         read_template = __read_template_hack
 
+    def _add_defaults_optional(self):
+        if six.PY2:
+            sdist_add_defaults._add_defaults_optional(self)
+        else:
+            super()._add_defaults_optional()
+        if os.path.isfile('pyproject.toml'):
+            self.filelist.append('pyproject.toml')
+
     def _add_defaults_python(self):
         """getting python files"""
         if self.distribution.has_pure_modules():

{"golden_diff": "diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py\n--- a/setuptools/command/sdist.py\n+++ b/setuptools/command/sdist.py\n@@ -121,6 +121,14 @@\n     if has_leaky_handle:\n         read_template = __read_template_hack\n \n+    def _add_defaults_optional(self):\n+        if six.PY2:\n+            sdist_add_defaults._add_defaults_optional(self)\n+        else:\n+            super()._add_defaults_optional()\n+        if os.path.isfile('pyproject.toml'):\n+            self.filelist.append('pyproject.toml')\n+\n     def _add_defaults_python(self):\n         \"\"\"getting python files\"\"\"\n         if self.distribution.has_pure_modules():\n", "issue": "pyproject.toml should be included in sdist by default\nAn issue came up at work recently where installing [python-daemon](https://pagure.io/python-daemon) with `pip` was hitting the `easy_install` path. I assumed it was because `python-daemon` didn't have a `pyproject.toml`, but it turns out they do - it's just not included in the `Manifest.in`, so it didn't get included in the `sdist`. To verify this I created a super basic example project and it does seem that the default is to exclude `pyproject.toml`.\r\n\r\nGiven that `pyproject.toml` is one of the most important files to have when executing a build, it should be included in the sdist unless explicitly excluded.\n", "before_files": [{"content": "from distutils import log\nimport distutils.command.sdist as orig\nimport os\nimport sys\nimport io\nimport contextlib\n\nfrom setuptools.extern import six, ordered_set\n\nfrom .py36compat import sdist_add_defaults\n\nimport pkg_resources\n\n_default_revctrl = list\n\n\ndef walk_revctrl(dirname=''):\n    \"\"\"Find all files under revision control\"\"\"\n    for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):\n        for item in ep.load()(dirname):\n            yield item\n\n\nclass sdist(sdist_add_defaults, orig.sdist):\n    \"\"\"Smart sdist that finds anything supported by revision control\"\"\"\n\n    user_options = [\n        ('formats=', None,\n         \"formats for source distribution (comma-separated list)\"),\n        ('keep-temp', 'k',\n         \"keep the distribution tree around after creating \" +\n         \"archive file(s)\"),\n        ('dist-dir=', 'd',\n         \"directory to put the source distribution archive(s) in \"\n         \"[default: dist]\"),\n    ]\n\n    negative_opt = {}\n\n    README_EXTENSIONS = ['', '.rst', '.txt', '.md']\n    READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS)\n\n    def run(self):\n        self.run_command('egg_info')\n        ei_cmd = self.get_finalized_command('egg_info')\n        self.filelist = ei_cmd.filelist\n        self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt'))\n        self.check_readme()\n\n        # Run sub commands\n        for cmd_name in self.get_sub_commands():\n            self.run_command(cmd_name)\n\n        self.make_distribution()\n\n        dist_files = getattr(self.distribution, 'dist_files', [])\n        for file in self.archive_files:\n            data = ('sdist', '', file)\n            if data not in dist_files:\n                dist_files.append(data)\n\n    def initialize_options(self):\n        orig.sdist.initialize_options(self)\n\n        self._default_to_gztar()\n\n    def _default_to_gztar(self):\n        # only needed on Python prior to 3.6.\n        if sys.version_info >= (3, 6, 0, 'beta', 1):\n            return\n        self.formats = ['gztar']\n\n    def make_distribution(self):\n        \"\"\"\n        Workaround for #516\n        \"\"\"\n        with self._remove_os_link():\n            orig.sdist.make_distribution(self)\n\n    @staticmethod\n    @contextlib.contextmanager\n    def _remove_os_link():\n        \"\"\"\n        In a context, remove and restore os.link if it exists\n        \"\"\"\n\n        class NoValue:\n            pass\n\n        orig_val = getattr(os, 'link', NoValue)\n        try:\n            del os.link\n        except Exception:\n            pass\n        try:\n            yield\n        finally:\n            if orig_val is not NoValue:\n                setattr(os, 'link', orig_val)\n\n    def __read_template_hack(self):\n        # This grody hack closes the template file (MANIFEST.in) if an\n        #  exception occurs during read_template.\n        # Doing so prevents an error when easy_install attempts to delete the\n        #  file.\n        try:\n            orig.sdist.read_template(self)\n        except Exception:\n            _, _, tb = sys.exc_info()\n            tb.tb_next.tb_frame.f_locals['template'].close()\n            raise\n\n    # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle\n    #  has been fixed, so only override the method if we're using an earlier\n    #  Python.\n    has_leaky_handle = (\n        sys.version_info < (2, 7, 2)\n        or (3, 0) <= sys.version_info < (3, 1, 4)\n        or (3, 2) <= sys.version_info < (3, 2, 1)\n    )\n    if has_leaky_handle:\n        read_template = __read_template_hack\n\n    def _add_defaults_python(self):\n        \"\"\"getting python files\"\"\"\n        if self.distribution.has_pure_modules():\n            build_py = self.get_finalized_command('build_py')\n            self.filelist.extend(build_py.get_source_files())\n            self._add_data_files(self._safe_data_files(build_py))\n\n    def _safe_data_files(self, build_py):\n        \"\"\"\n        Extracting data_files from build_py is known to cause\n        infinite recursion errors when `include_package_data`\n        is enabled, so suppress it in that case.\n        \"\"\"\n        if self.distribution.include_package_data:\n            return ()\n        return build_py.data_files\n\n    def _add_data_files(self, data_files):\n        \"\"\"\n        Add data files as found in build_py.data_files.\n        \"\"\"\n        self.filelist.extend(\n            os.path.join(src_dir, name)\n            for _, src_dir, _, filenames in data_files\n            for name in filenames\n        )\n\n    def _add_defaults_data_files(self):\n        try:\n            if six.PY2:\n                sdist_add_defaults._add_defaults_data_files(self)\n            else:\n                super()._add_defaults_data_files()\n        except TypeError:\n            log.warn(\"data_files contains unexpected objects\")\n\n    def check_readme(self):\n        for f in self.READMES:\n            if os.path.exists(f):\n                return\n        else:\n            self.warn(\n                \"standard file not found: should have one of \" +\n                ', '.join(self.READMES)\n            )\n\n    def make_release_tree(self, base_dir, files):\n        orig.sdist.make_release_tree(self, base_dir, files)\n\n        # Save any egg_info command line options used to create this sdist\n        dest = os.path.join(base_dir, 'setup.cfg')\n        if hasattr(os, 'link') and os.path.exists(dest):\n            # unlink and re-copy, since it might be hard-linked, and\n            # we don't want to change the source version\n            os.unlink(dest)\n            self.copy_file('setup.cfg', dest)\n\n        self.get_finalized_command('egg_info').save_version_info(dest)\n\n    def _manifest_is_not_generated(self):\n        # check for special comment used in 2.7.1 and higher\n        if not os.path.isfile(self.manifest):\n            return False\n\n        with io.open(self.manifest, 'rb') as fp:\n            first_line = fp.readline()\n        return (first_line !=\n                '# file GENERATED by distutils, do NOT edit\\n'.encode())\n\n    def read_manifest(self):\n        \"\"\"Read the manifest file (named by 'self.manifest') and use it to\n        fill in 'self.filelist', the list of files to include in the source\n        distribution.\n        \"\"\"\n        log.info(\"reading manifest file '%s'\", self.manifest)\n        manifest = open(self.manifest, 'rb')\n        for line in manifest:\n            # The manifest must contain UTF-8. See #303.\n            if six.PY3:\n                try:\n                    line = line.decode('UTF-8')\n                except UnicodeDecodeError:\n                    log.warn(\"%r not UTF-8 decodable -- skipping\" % line)\n                    continue\n            # ignore comments and blank lines\n            line = line.strip()\n            if line.startswith('#') or not line:\n                continue\n            self.filelist.append(line)\n        manifest.close()\n\n    def check_license(self):\n        \"\"\"Checks if license_file' or 'license_files' is configured and adds any\n        valid paths to 'self.filelist'.\n        \"\"\"\n\n        files = ordered_set.OrderedSet()\n\n        opts = self.distribution.get_option_dict('metadata')\n\n        # ignore the source of the value\n        _, license_file = opts.get('license_file', (None, None))\n\n        if license_file is None:\n            log.debug(\"'license_file' option was not specified\")\n        else:\n            files.add(license_file)\n\n        try:\n            files.update(self.distribution.metadata.license_files)\n        except TypeError:\n            log.warn(\"warning: 'license_files' option is malformed\")\n\n        for f in files:\n            if not os.path.exists(f):\n                log.warn(\n                    \"warning: Failed to find the configured license file '%s'\",\n                    f)\n                files.remove(f)\n\n        self.filelist.extend(files)\n", "path": "setuptools/command/sdist.py"}], "after_files": [{"content": "from distutils import log\nimport distutils.command.sdist as orig\nimport os\nimport sys\nimport io\nimport contextlib\n\nfrom setuptools.extern import six, ordered_set\n\nfrom .py36compat import sdist_add_defaults\n\nimport pkg_resources\n\n_default_revctrl = list\n\n\ndef walk_revctrl(dirname=''):\n    \"\"\"Find all files under revision control\"\"\"\n    for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):\n        for item in ep.load()(dirname):\n            yield item\n\n\nclass sdist(sdist_add_defaults, orig.sdist):\n    \"\"\"Smart sdist that finds anything supported by revision control\"\"\"\n\n    user_options = [\n        ('formats=', None,\n         \"formats for source distribution (comma-separated list)\"),\n        ('keep-temp', 'k',\n         \"keep the distribution tree around after creating \" +\n         \"archive file(s)\"),\n        ('dist-dir=', 'd',\n         \"directory to put the source distribution archive(s) in \"\n         \"[default: dist]\"),\n    ]\n\n    negative_opt = {}\n\n    README_EXTENSIONS = ['', '.rst', '.txt', '.md']\n    READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS)\n\n    def run(self):\n        self.run_command('egg_info')\n        ei_cmd = self.get_finalized_command('egg_info')\n        self.filelist = ei_cmd.filelist\n        self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt'))\n        self.check_readme()\n\n        # Run sub commands\n        for cmd_name in self.get_sub_commands():\n            self.run_command(cmd_name)\n\n        self.make_distribution()\n\n        dist_files = getattr(self.distribution, 'dist_files', [])\n        for file in self.archive_files:\n            data = ('sdist', '', file)\n            if data not in dist_files:\n                dist_files.append(data)\n\n    def initialize_options(self):\n        orig.sdist.initialize_options(self)\n\n        self._default_to_gztar()\n\n    def _default_to_gztar(self):\n        # only needed on Python prior to 3.6.\n        if sys.version_info >= (3, 6, 0, 'beta', 1):\n            return\n        self.formats = ['gztar']\n\n    def make_distribution(self):\n        \"\"\"\n        Workaround for #516\n        \"\"\"\n        with self._remove_os_link():\n            orig.sdist.make_distribution(self)\n\n    @staticmethod\n    @contextlib.contextmanager\n    def _remove_os_link():\n        \"\"\"\n        In a context, remove and restore os.link if it exists\n        \"\"\"\n\n        class NoValue:\n            pass\n\n        orig_val = getattr(os, 'link', NoValue)\n        try:\n            del os.link\n        except Exception:\n            pass\n        try:\n            yield\n        finally:\n            if orig_val is not NoValue:\n                setattr(os, 'link', orig_val)\n\n    def __read_template_hack(self):\n        # This grody hack closes the template file (MANIFEST.in) if an\n        #  exception occurs during read_template.\n        # Doing so prevents an error when easy_install attempts to delete the\n        #  file.\n        try:\n            orig.sdist.read_template(self)\n        except Exception:\n            _, _, tb = sys.exc_info()\n            tb.tb_next.tb_frame.f_locals['template'].close()\n            raise\n\n    # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle\n    #  has been fixed, so only override the method if we're using an earlier\n    #  Python.\n    has_leaky_handle = (\n        sys.version_info < (2, 7, 2)\n        or (3, 0) <= sys.version_info < (3, 1, 4)\n        or (3, 2) <= sys.version_info < (3, 2, 1)\n    )\n    if has_leaky_handle:\n        read_template = __read_template_hack\n\n    def _add_defaults_optional(self):\n        if six.PY2:\n            sdist_add_defaults._add_defaults_optional(self)\n        else:\n            super()._add_defaults_optional()\n        if os.path.isfile('pyproject.toml'):\n            self.filelist.append('pyproject.toml')\n\n    def _add_defaults_python(self):\n        \"\"\"getting python files\"\"\"\n        if self.distribution.has_pure_modules():\n            build_py = self.get_finalized_command('build_py')\n            self.filelist.extend(build_py.get_source_files())\n            self._add_data_files(self._safe_data_files(build_py))\n\n    def _safe_data_files(self, build_py):\n        \"\"\"\n        Extracting data_files from build_py is known to cause\n        infinite recursion errors when `include_package_data`\n        is enabled, so suppress it in that case.\n        \"\"\"\n        if self.distribution.include_package_data:\n            return ()\n        return build_py.data_files\n\n    def _add_data_files(self, data_files):\n        \"\"\"\n        Add data files as found in build_py.data_files.\n        \"\"\"\n        self.filelist.extend(\n            os.path.join(src_dir, name)\n            for _, src_dir, _, filenames in data_files\n            for name in filenames\n        )\n\n    def _add_defaults_data_files(self):\n        try:\n            if six.PY2:\n                sdist_add_defaults._add_defaults_data_files(self)\n            else:\n                super()._add_defaults_data_files()\n        except TypeError:\n            log.warn(\"data_files contains unexpected objects\")\n\n    def check_readme(self):\n        for f in self.READMES:\n            if os.path.exists(f):\n                return\n        else:\n            self.warn(\n                \"standard file not found: should have one of \" +\n                ', '.join(self.READMES)\n            )\n\n    def make_release_tree(self, base_dir, files):\n        orig.sdist.make_release_tree(self, base_dir, files)\n\n        # Save any egg_info command line options used to create this sdist\n        dest = os.path.join(base_dir, 'setup.cfg')\n        if hasattr(os, 'link') and os.path.exists(dest):\n            # unlink and re-copy, since it might be hard-linked, and\n            # we don't want to change the source version\n            os.unlink(dest)\n            self.copy_file('setup.cfg', dest)\n\n        self.get_finalized_command('egg_info').save_version_info(dest)\n\n    def _manifest_is_not_generated(self):\n        # check for special comment used in 2.7.1 and higher\n        if not os.path.isfile(self.manifest):\n            return False\n\n        with io.open(self.manifest, 'rb') as fp:\n            first_line = fp.readline()\n        return (first_line !=\n                '# file GENERATED by distutils, do NOT edit\\n'.encode())\n\n    def read_manifest(self):\n        \"\"\"Read the manifest file (named by 'self.manifest') and use it to\n        fill in 'self.filelist', the list of files to include in the source\n        distribution.\n        \"\"\"\n        log.info(\"reading manifest file '%s'\", self.manifest)\n        manifest = open(self.manifest, 'rb')\n        for line in manifest:\n            # The manifest must contain UTF-8. See #303.\n            if six.PY3:\n                try:\n                    line = line.decode('UTF-8')\n                except UnicodeDecodeError:\n                    log.warn(\"%r not UTF-8 decodable -- skipping\" % line)\n                    continue\n            # ignore comments and blank lines\n            line = line.strip()\n            if line.startswith('#') or not line:\n                continue\n            self.filelist.append(line)\n        manifest.close()\n\n    def check_license(self):\n        \"\"\"Checks if license_file' or 'license_files' is configured and adds any\n        valid paths to 'self.filelist'.\n        \"\"\"\n\n        files = ordered_set.OrderedSet()\n\n        opts = self.distribution.get_option_dict('metadata')\n\n        # ignore the source of the value\n        _, license_file = opts.get('license_file', (None, None))\n\n        if license_file is None:\n            log.debug(\"'license_file' option was not specified\")\n        else:\n            files.add(license_file)\n\n        try:\n            files.update(self.distribution.metadata.license_files)\n        except TypeError:\n            log.warn(\"warning: 'license_files' option is malformed\")\n\n        for f in files:\n            if not os.path.exists(f):\n                log.warn(\n                    \"warning: Failed to find the configured license file '%s'\",\n                    f)\n                files.remove(f)\n\n        self.filelist.extend(files)\n", "path": "setuptools/command/sdist.py"}]}