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
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             # This functionality is incompatible with include_package_data, and
130             # will in fact create an infinite recursion if include_package_data
131             # is True.  Use of include_package_data will imply that
132             # distutils-style automatic handling of package_data is disabled
133             if not self.distribution.include_package_data:
134                 for _, src_dir, _, filenames in build_py.data_files:
135                     self.filelist.extend([os.path.join(src_dir, filename)
136                                           for filename in filenames])
137 
138     def _add_defaults_data_files(self):
139         try:
140             if six.PY2:
141                 sdist_add_defaults._add_defaults_data_files(self)
142             else:
143                 super()._add_defaults_data_files()
144         except TypeError:
145             log.warn("data_files contains unexpected objects")
146 
147     def check_readme(self):
148         for f in self.READMES:
149             if os.path.exists(f):
150                 return
151         else:
152             self.warn(
153                 "standard file not found: should have one of " +
154                 ', '.join(self.READMES)
155             )
156 
157     def make_release_tree(self, base_dir, files):
158         orig.sdist.make_release_tree(self, base_dir, files)
159 
160         # Save any egg_info command line options used to create this sdist
161         dest = os.path.join(base_dir, 'setup.cfg')
162         if hasattr(os, 'link') and os.path.exists(dest):
163             # unlink and re-copy, since it might be hard-linked, and
164             # we don't want to change the source version
165             os.unlink(dest)
166             self.copy_file('setup.cfg', dest)
167 
168         self.get_finalized_command('egg_info').save_version_info(dest)
169 
170     def _manifest_is_not_generated(self):
171         # check for special comment used in 2.7.1 and higher
172         if not os.path.isfile(self.manifest):
173             return False
174 
175         with io.open(self.manifest, 'rb') as fp:
176             first_line = fp.readline()
177         return (first_line !=
178                 '# file GENERATED by distutils, do NOT edit\n'.encode())
179 
180     def read_manifest(self):
181         """Read the manifest file (named by 'self.manifest') and use it to
182         fill in 'self.filelist', the list of files to include in the source
183         distribution.
184         """
185         log.info("reading manifest file '%s'", self.manifest)
186         manifest = open(self.manifest, 'rb')
187         for line in manifest:
188             # The manifest must contain UTF-8. See #303.
189             if six.PY3:
190                 try:
191                     line = line.decode('UTF-8')
192                 except UnicodeDecodeError:
193                     log.warn("%r not UTF-8 decodable -- skipping" % line)
194                     continue
195             # ignore comments and blank lines
196             line = line.strip()
197             if line.startswith('#') or not line:
198                 continue
199             self.filelist.append(line)
200         manifest.close()
201
```
--- 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\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            # This functionality is incompatible with include_package_data, and\n            # will in fact create an infinite recursion if include_package_data\n            # is True.  Use of include_package_data will imply that\n            # distutils-style automatic handling of package_data is disabled\n            if not self.distribution.include_package_data:\n                for _, src_dir, _, filenames in build_py.data_files:\n                    self.filelist.extend([os.path.join(src_dir, filename)\n                                          for filename in filenames])\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", "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\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            # This functionality is incompatible with include_package_data, and\n            # will in fact create an infinite recursion if include_package_data\n            # is True.  Use of include_package_data will imply that\n            # distutils-style automatic handling of package_data is disabled\n            if not self.distribution.include_package_data:\n                for _, src_dir, _, filenames in build_py.data_files:\n                    self.filelist.extend([os.path.join(src_dir, filename)\n                                          for filename in filenames])\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", "path": "setuptools/command/sdist.py"}]}