We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
poetry install does not honor `build-system.requires`
<!--
  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] -->
- [ ] I am on the [latest](https://github.com/python-poetry/poetry/releases/latest) Poetry version.
- [x] I have searched the [issues](https://github.com/python-poetry/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 20.04.4
- **Poetry version**: 1.2.0b2
- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**:
<details>
<summary>pyproject.toml</summary>

```
[tool.poetry]
name = "meow"
version = "0.1.0"
description = ""
authors = [""]
build = "build.py"

[tool.poetry.dependencies]
python = "^3.9"
SoundFile = "0.10.*"
crcmod = "^1.7"
librosa = ">=0.8.0"
numba = "^0.56.0"
protobuf = "3.14.0"
tensorboard = "^2.10.0"
torchaudio = {version = "=0.12.1+cu113", source="torch"}
torch = {version = "=1.12.1+cu113", source="torch"}

[[tool.poetry.source]]
name = "torch"
url = "https://download.pytorch.org/whl/cu113"
secondary = true

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry-core>=1.0.0", "setuptools>=40.6.0", "wheel", "numpy", "pybind11"]
build-backend = "poetry.core.masonry.api"
```

</details>

## Issue
<!-- Now feel free to write your issue, but please be descriptive! Thanks again 🙌 ❤️ -->
Running `poetry build` with the above `pyproject.toml` does the right thing:
```
Preparing build environment with build-system requirements poetry-core>=1.0.0, setuptools>=40.6.0, wheel, numpy, pybind11
[...snip...]
```

Running `poetry install` fails because it attempts to build the project without installing `build-system.requires` packages.

I would have expected the install command to create an isolated environment, install the build requirements and perform the build in that isolated environment, and then install the produced artifact in my current environment.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/poetry/masonry/builders/editable.py`
Content:
```
1 from __future__ import annotations
2 
3 import csv
4 import hashlib
5 import json
6 import os
7 
8 from base64 import urlsafe_b64encode
9 from pathlib import Path
10 from typing import TYPE_CHECKING
11 
12 from poetry.core.constraints.version import Version
13 from poetry.core.masonry.builders.builder import Builder
14 from poetry.core.masonry.builders.sdist import SdistBuilder
15 from poetry.core.masonry.utils.package_include import PackageInclude
16 
17 from poetry.utils._compat import WINDOWS
18 from poetry.utils._compat import decode
19 from poetry.utils.env import build_environment
20 from poetry.utils.helpers import is_dir_writable
21 from poetry.utils.pip import pip_install
22 
23 
24 if TYPE_CHECKING:
25     from cleo.io.io import IO
26 
27     from poetry.poetry import Poetry
28     from poetry.utils.env import Env
29 
30 SCRIPT_TEMPLATE = """\
31 #!{python}
32 import sys
33 from {module} import {callable_holder}
34 
35 if __name__ == '__main__':
36     sys.exit({callable_}())
37 """
38 
39 WINDOWS_CMD_TEMPLATE = """\
40 @echo off\r\n"{python}" "%~dp0\\{script}" %*\r\n
41 """
42 
43 
44 class EditableBuilder(Builder):
45     def __init__(self, poetry: Poetry, env: Env, io: IO) -> None:
46         self._poetry: Poetry
47         super().__init__(poetry)
48 
49         self._env = env
50         self._io = io
51 
52     def build(self, target_dir: Path | None = None) -> Path:
53         self._debug(
54             f"  - Building package <c1>{self._package.name}</c1> in"
55             " <info>editable</info> mode"
56         )
57 
58         if self._package.build_script:
59             if self._package.build_should_generate_setup():
60                 self._debug(
61                     "  - <warning>Falling back on using a <b>setup.py</b></warning>"
62                 )
63                 self._setup_build()
64                 path: Path = self._path
65                 return path
66 
67             self._run_build_script(self._package.build_script)
68 
69         for removed in self._env.site_packages.remove_distribution_files(
70             distribution_name=self._package.name
71         ):
72             self._debug(
73                 f"  - Removed <c2>{removed.name}</c2> directory from"
74                 f" <b>{removed.parent}</b>"
75             )
76 
77         added_files = []
78         added_files += self._add_pth()
79         added_files += self._add_scripts()
80         self._add_dist_info(added_files)
81 
82         path = self._path
83         return path
84 
85     def _run_build_script(self, build_script: str) -> None:
86         with build_environment(poetry=self._poetry, env=self._env, io=self._io) as env:
87             self._debug(f"  - Executing build script: <b>{build_script}</b>")
88             env.run("python", str(self._path.joinpath(build_script)), call=True)
89 
90     def _setup_build(self) -> None:
91         builder = SdistBuilder(self._poetry)
92         setup = self._path / "setup.py"
93         has_setup = setup.exists()
94 
95         if has_setup:
96             self._io.write_error_line(
97                 "<warning>A setup.py file already exists. Using it.</warning>"
98             )
99         else:
100             with setup.open("w", encoding="utf-8") as f:
101                 f.write(decode(builder.build_setup()))
102 
103         try:
104             if self._env.pip_version < Version.from_parts(19, 0):
105                 pip_install(self._path, self._env, upgrade=True, editable=True)
106             else:
107                 # Temporarily rename pyproject.toml
108                 renamed_pyproject = self._poetry.file.path.with_suffix(".tmp")
109                 self._poetry.file.path.rename(renamed_pyproject)
110                 try:
111                     pip_install(self._path, self._env, upgrade=True, editable=True)
112                 finally:
113                     renamed_pyproject.rename(self._poetry.file.path)
114         finally:
115             if not has_setup:
116                 os.remove(setup)
117 
118     def _add_pth(self) -> list[Path]:
119         paths = {
120             include.base.resolve().as_posix()
121             for include in self._module.includes
122             if isinstance(include, PackageInclude)
123             and (include.is_module() or include.is_package())
124         }
125 
126         content = "".join(decode(path + os.linesep) for path in paths)
127         pth_file = Path(self._module.name).with_suffix(".pth")
128 
129         # remove any pre-existing pth files for this package
130         for file in self._env.site_packages.find(path=pth_file, writable_only=True):
131             self._debug(
132                 f"  - Removing existing <c2>{file.name}</c2> from <b>{file.parent}</b>"
133                 f" for {self._poetry.file.path.parent}"
134             )
135             file.unlink(missing_ok=True)
136 
137         try:
138             pth_file = self._env.site_packages.write_text(
139                 pth_file, content, encoding="utf-8"
140             )
141             self._debug(
142                 f"  - Adding <c2>{pth_file.name}</c2> to <b>{pth_file.parent}</b> for"
143                 f" {self._poetry.file.path.parent}"
144             )
145             return [pth_file]
146         except OSError:
147             # TODO: Replace with PermissionError
148             self._io.write_error_line(
149                 f"  - Failed to create <c2>{pth_file.name}</c2> for"
150                 f" {self._poetry.file.path.parent}"
151             )
152             return []
153 
154     def _add_scripts(self) -> list[Path]:
155         added = []
156         entry_points = self.convert_entry_points()
157 
158         for scripts_path in self._env.script_dirs:
159             if is_dir_writable(path=scripts_path, create=True):
160                 break
161         else:
162             self._io.write_error_line(
163                 "  - Failed to find a suitable script installation directory for"
164                 f" {self._poetry.file.path.parent}"
165             )
166             return []
167 
168         scripts = entry_points.get("console_scripts", [])
169         for script in scripts:
170             name, script = script.split(" = ")
171             module, callable_ = script.split(":")
172             callable_holder = callable_.split(".", 1)[0]
173 
174             script_file = scripts_path.joinpath(name)
175             self._debug(
176                 f"  - Adding the <c2>{name}</c2> script to <b>{scripts_path}</b>"
177             )
178             with script_file.open("w", encoding="utf-8") as f:
179                 f.write(
180                     decode(
181                         SCRIPT_TEMPLATE.format(
182                             python=self._env.python,
183                             module=module,
184                             callable_holder=callable_holder,
185                             callable_=callable_,
186                         )
187                     )
188                 )
189 
190             script_file.chmod(0o755)
191 
192             added.append(script_file)
193 
194             if WINDOWS:
195                 cmd_script = script_file.with_suffix(".cmd")
196                 cmd = WINDOWS_CMD_TEMPLATE.format(python=self._env.python, script=name)
197                 self._debug(
198                     f"  - Adding the <c2>{cmd_script.name}</c2> script wrapper to"
199                     f" <b>{scripts_path}</b>"
200                 )
201 
202                 with cmd_script.open("w", encoding="utf-8") as f:
203                     f.write(decode(cmd))
204 
205                 added.append(cmd_script)
206 
207         return added
208 
209     def _add_dist_info(self, added_files: list[Path]) -> None:
210         from poetry.core.masonry.builders.wheel import WheelBuilder
211 
212         added_files = added_files[:]
213 
214         builder = WheelBuilder(self._poetry)
215         dist_info = self._env.site_packages.mkdir(Path(builder.dist_info))
216 
217         self._debug(
218             f"  - Adding the <c2>{dist_info.name}</c2> directory to"
219             f" <b>{dist_info.parent}</b>"
220         )
221 
222         with dist_info.joinpath("METADATA").open("w", encoding="utf-8") as f:
223             builder._write_metadata_file(f)
224 
225         added_files.append(dist_info.joinpath("METADATA"))
226 
227         with dist_info.joinpath("INSTALLER").open("w", encoding="utf-8") as f:
228             f.write("poetry")
229 
230         added_files.append(dist_info.joinpath("INSTALLER"))
231 
232         if self.convert_entry_points():
233             with dist_info.joinpath("entry_points.txt").open(
234                 "w", encoding="utf-8"
235             ) as f:
236                 builder._write_entry_points(f)
237 
238             added_files.append(dist_info.joinpath("entry_points.txt"))
239 
240         # write PEP 610 metadata
241         direct_url_json = dist_info.joinpath("direct_url.json")
242         direct_url_json.write_text(
243             json.dumps(
244                 {
245                     "dir_info": {"editable": True},
246                     "url": self._poetry.file.path.parent.absolute().as_uri(),
247                 }
248             )
249         )
250         added_files.append(direct_url_json)
251 
252         record = dist_info.joinpath("RECORD")
253         with record.open("w", encoding="utf-8", newline="") as f:
254             csv_writer = csv.writer(f)
255             for path in added_files:
256                 hash = self._get_file_hash(path)
257                 size = path.stat().st_size
258                 csv_writer.writerow((path, f"sha256={hash}", size))
259 
260             # RECORD itself is recorded with no hash or size
261             csv_writer.writerow((record, "", ""))
262 
263     def _get_file_hash(self, filepath: Path) -> str:
264         hashsum = hashlib.sha256()
265         with filepath.open("rb") as src:
266             while True:
267                 buf = src.read(1024 * 8)
268                 if not buf:
269                     break
270                 hashsum.update(buf)
271 
272             src.seek(0)
273 
274         return urlsafe_b64encode(hashsum.digest()).decode("ascii").rstrip("=")
275 
276     def _debug(self, msg: str) -> None:
277         if self._io.is_debug():
278             self._io.write_line(msg)
279
```
--- 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/src/poetry/masonry/builders/editable.py b/src/poetry/masonry/builders/editable.py
--- a/src/poetry/masonry/builders/editable.py
+++ b/src/poetry/masonry/builders/editable.py
@@ -9,7 +9,6 @@
 from pathlib import Path
 from typing import TYPE_CHECKING
 
-from poetry.core.constraints.version import Version
 from poetry.core.masonry.builders.builder import Builder
 from poetry.core.masonry.builders.sdist import SdistBuilder
 from poetry.core.masonry.utils.package_include import PackageInclude
@@ -101,16 +100,7 @@
                 f.write(decode(builder.build_setup()))
 
         try:
-            if self._env.pip_version < Version.from_parts(19, 0):
-                pip_install(self._path, self._env, upgrade=True, editable=True)
-            else:
-                # Temporarily rename pyproject.toml
-                renamed_pyproject = self._poetry.file.path.with_suffix(".tmp")
-                self._poetry.file.path.rename(renamed_pyproject)
-                try:
-                    pip_install(self._path, self._env, upgrade=True, editable=True)
-                finally:
-                    renamed_pyproject.rename(self._poetry.file.path)
+            pip_install(self._path, self._env, upgrade=True, editable=True)
         finally:
             if not has_setup:
                 os.remove(setup)

{"golden_diff": "diff --git a/src/poetry/masonry/builders/editable.py b/src/poetry/masonry/builders/editable.py\n--- a/src/poetry/masonry/builders/editable.py\n+++ b/src/poetry/masonry/builders/editable.py\n@@ -9,7 +9,6 @@\n from pathlib import Path\n from typing import TYPE_CHECKING\n \n-from poetry.core.constraints.version import Version\n from poetry.core.masonry.builders.builder import Builder\n from poetry.core.masonry.builders.sdist import SdistBuilder\n from poetry.core.masonry.utils.package_include import PackageInclude\n@@ -101,16 +100,7 @@\n                 f.write(decode(builder.build_setup()))\n \n         try:\n-            if self._env.pip_version < Version.from_parts(19, 0):\n-                pip_install(self._path, self._env, upgrade=True, editable=True)\n-            else:\n-                # Temporarily rename pyproject.toml\n-                renamed_pyproject = self._poetry.file.path.with_suffix(\".tmp\")\n-                self._poetry.file.path.rename(renamed_pyproject)\n-                try:\n-                    pip_install(self._path, self._env, upgrade=True, editable=True)\n-                finally:\n-                    renamed_pyproject.rename(self._poetry.file.path)\n+            pip_install(self._path, self._env, upgrade=True, editable=True)\n         finally:\n             if not has_setup:\n                 os.remove(setup)\n", "issue": "poetry install does not honor `build-system.requires`\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- [ ] I am on the [latest](https://github.com/python-poetry/poetry/releases/latest) Poetry version.\r\n- [x] I have searched the [issues](https://github.com/python-poetry/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 20.04.4\r\n- **Poetry version**: 1.2.0b2\r\n- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**:\r\n<details>\r\n<summary>pyproject.toml</summary>\r\n\r\n```\r\n[tool.poetry]\r\nname = \"meow\"\r\nversion = \"0.1.0\"\r\ndescription = \"\"\r\nauthors = [\"\"]\r\nbuild = \"build.py\"\r\n\r\n[tool.poetry.dependencies]\r\npython = \"^3.9\"\r\nSoundFile = \"0.10.*\"\r\ncrcmod = \"^1.7\"\r\nlibrosa = \">=0.8.0\"\r\nnumba = \"^0.56.0\"\r\nprotobuf = \"3.14.0\"\r\ntensorboard = \"^2.10.0\"\r\ntorchaudio = {version = \"=0.12.1+cu113\", source=\"torch\"}\r\ntorch = {version = \"=1.12.1+cu113\", source=\"torch\"}\r\n\r\n[[tool.poetry.source]]\r\nname = \"torch\"\r\nurl = \"https://download.pytorch.org/whl/cu113\"\r\nsecondary = true\r\n\r\n[tool.poetry.dev-dependencies]\r\n\r\n[build-system]\r\nrequires = [\"poetry-core>=1.0.0\", \"setuptools>=40.6.0\", \"wheel\", \"numpy\", \"pybind11\"]\r\nbuild-backend = \"poetry.core.masonry.api\"\r\n```\r\n\r\n</details>\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\nRunning `poetry build` with the above `pyproject.toml` does the right thing:\r\n```\r\nPreparing build environment with build-system requirements poetry-core>=1.0.0, setuptools>=40.6.0, wheel, numpy, pybind11\r\n[...snip...]\r\n```\r\n\r\nRunning `poetry install` fails because it attempts to build the project without installing `build-system.requires` packages.\r\n\r\nI would have expected the install command to create an isolated environment, install the build requirements and perform the build in that isolated environment, and then install the produced artifact in my current environment.\n", "before_files": [{"content": "from __future__ import annotations\n\nimport csv\nimport hashlib\nimport json\nimport os\n\nfrom base64 import urlsafe_b64encode\nfrom pathlib import Path\nfrom typing import TYPE_CHECKING\n\nfrom poetry.core.constraints.version import Version\nfrom poetry.core.masonry.builders.builder import Builder\nfrom poetry.core.masonry.builders.sdist import SdistBuilder\nfrom poetry.core.masonry.utils.package_include import PackageInclude\n\nfrom poetry.utils._compat import WINDOWS\nfrom poetry.utils._compat import decode\nfrom poetry.utils.env import build_environment\nfrom poetry.utils.helpers import is_dir_writable\nfrom poetry.utils.pip import pip_install\n\n\nif TYPE_CHECKING:\n    from cleo.io.io import IO\n\n    from poetry.poetry import Poetry\n    from poetry.utils.env import Env\n\nSCRIPT_TEMPLATE = \"\"\"\\\n#!{python}\nimport sys\nfrom {module} import {callable_holder}\n\nif __name__ == '__main__':\n    sys.exit({callable_}())\n\"\"\"\n\nWINDOWS_CMD_TEMPLATE = \"\"\"\\\n@echo off\\r\\n\"{python}\" \"%~dp0\\\\{script}\" %*\\r\\n\n\"\"\"\n\n\nclass EditableBuilder(Builder):\n    def __init__(self, poetry: Poetry, env: Env, io: IO) -> None:\n        self._poetry: Poetry\n        super().__init__(poetry)\n\n        self._env = env\n        self._io = io\n\n    def build(self, target_dir: Path | None = None) -> Path:\n        self._debug(\n            f\"  - Building package <c1>{self._package.name}</c1> in\"\n            \" <info>editable</info> mode\"\n        )\n\n        if self._package.build_script:\n            if self._package.build_should_generate_setup():\n                self._debug(\n                    \"  - <warning>Falling back on using a <b>setup.py</b></warning>\"\n                )\n                self._setup_build()\n                path: Path = self._path\n                return path\n\n            self._run_build_script(self._package.build_script)\n\n        for removed in self._env.site_packages.remove_distribution_files(\n            distribution_name=self._package.name\n        ):\n            self._debug(\n                f\"  - Removed <c2>{removed.name}</c2> directory from\"\n                f\" <b>{removed.parent}</b>\"\n            )\n\n        added_files = []\n        added_files += self._add_pth()\n        added_files += self._add_scripts()\n        self._add_dist_info(added_files)\n\n        path = self._path\n        return path\n\n    def _run_build_script(self, build_script: str) -> None:\n        with build_environment(poetry=self._poetry, env=self._env, io=self._io) as env:\n            self._debug(f\"  - Executing build script: <b>{build_script}</b>\")\n            env.run(\"python\", str(self._path.joinpath(build_script)), call=True)\n\n    def _setup_build(self) -> None:\n        builder = SdistBuilder(self._poetry)\n        setup = self._path / \"setup.py\"\n        has_setup = setup.exists()\n\n        if has_setup:\n            self._io.write_error_line(\n                \"<warning>A setup.py file already exists. Using it.</warning>\"\n            )\n        else:\n            with setup.open(\"w\", encoding=\"utf-8\") as f:\n                f.write(decode(builder.build_setup()))\n\n        try:\n            if self._env.pip_version < Version.from_parts(19, 0):\n                pip_install(self._path, self._env, upgrade=True, editable=True)\n            else:\n                # Temporarily rename pyproject.toml\n                renamed_pyproject = self._poetry.file.path.with_suffix(\".tmp\")\n                self._poetry.file.path.rename(renamed_pyproject)\n                try:\n                    pip_install(self._path, self._env, upgrade=True, editable=True)\n                finally:\n                    renamed_pyproject.rename(self._poetry.file.path)\n        finally:\n            if not has_setup:\n                os.remove(setup)\n\n    def _add_pth(self) -> list[Path]:\n        paths = {\n            include.base.resolve().as_posix()\n            for include in self._module.includes\n            if isinstance(include, PackageInclude)\n            and (include.is_module() or include.is_package())\n        }\n\n        content = \"\".join(decode(path + os.linesep) for path in paths)\n        pth_file = Path(self._module.name).with_suffix(\".pth\")\n\n        # remove any pre-existing pth files for this package\n        for file in self._env.site_packages.find(path=pth_file, writable_only=True):\n            self._debug(\n                f\"  - Removing existing <c2>{file.name}</c2> from <b>{file.parent}</b>\"\n                f\" for {self._poetry.file.path.parent}\"\n            )\n            file.unlink(missing_ok=True)\n\n        try:\n            pth_file = self._env.site_packages.write_text(\n                pth_file, content, encoding=\"utf-8\"\n            )\n            self._debug(\n                f\"  - Adding <c2>{pth_file.name}</c2> to <b>{pth_file.parent}</b> for\"\n                f\" {self._poetry.file.path.parent}\"\n            )\n            return [pth_file]\n        except OSError:\n            # TODO: Replace with PermissionError\n            self._io.write_error_line(\n                f\"  - Failed to create <c2>{pth_file.name}</c2> for\"\n                f\" {self._poetry.file.path.parent}\"\n            )\n            return []\n\n    def _add_scripts(self) -> list[Path]:\n        added = []\n        entry_points = self.convert_entry_points()\n\n        for scripts_path in self._env.script_dirs:\n            if is_dir_writable(path=scripts_path, create=True):\n                break\n        else:\n            self._io.write_error_line(\n                \"  - Failed to find a suitable script installation directory for\"\n                f\" {self._poetry.file.path.parent}\"\n            )\n            return []\n\n        scripts = entry_points.get(\"console_scripts\", [])\n        for script in scripts:\n            name, script = script.split(\" = \")\n            module, callable_ = script.split(\":\")\n            callable_holder = callable_.split(\".\", 1)[0]\n\n            script_file = scripts_path.joinpath(name)\n            self._debug(\n                f\"  - Adding the <c2>{name}</c2> script to <b>{scripts_path}</b>\"\n            )\n            with script_file.open(\"w\", encoding=\"utf-8\") as f:\n                f.write(\n                    decode(\n                        SCRIPT_TEMPLATE.format(\n                            python=self._env.python,\n                            module=module,\n                            callable_holder=callable_holder,\n                            callable_=callable_,\n                        )\n                    )\n                )\n\n            script_file.chmod(0o755)\n\n            added.append(script_file)\n\n            if WINDOWS:\n                cmd_script = script_file.with_suffix(\".cmd\")\n                cmd = WINDOWS_CMD_TEMPLATE.format(python=self._env.python, script=name)\n                self._debug(\n                    f\"  - Adding the <c2>{cmd_script.name}</c2> script wrapper to\"\n                    f\" <b>{scripts_path}</b>\"\n                )\n\n                with cmd_script.open(\"w\", encoding=\"utf-8\") as f:\n                    f.write(decode(cmd))\n\n                added.append(cmd_script)\n\n        return added\n\n    def _add_dist_info(self, added_files: list[Path]) -> None:\n        from poetry.core.masonry.builders.wheel import WheelBuilder\n\n        added_files = added_files[:]\n\n        builder = WheelBuilder(self._poetry)\n        dist_info = self._env.site_packages.mkdir(Path(builder.dist_info))\n\n        self._debug(\n            f\"  - Adding the <c2>{dist_info.name}</c2> directory to\"\n            f\" <b>{dist_info.parent}</b>\"\n        )\n\n        with dist_info.joinpath(\"METADATA\").open(\"w\", encoding=\"utf-8\") as f:\n            builder._write_metadata_file(f)\n\n        added_files.append(dist_info.joinpath(\"METADATA\"))\n\n        with dist_info.joinpath(\"INSTALLER\").open(\"w\", encoding=\"utf-8\") as f:\n            f.write(\"poetry\")\n\n        added_files.append(dist_info.joinpath(\"INSTALLER\"))\n\n        if self.convert_entry_points():\n            with dist_info.joinpath(\"entry_points.txt\").open(\n                \"w\", encoding=\"utf-8\"\n            ) as f:\n                builder._write_entry_points(f)\n\n            added_files.append(dist_info.joinpath(\"entry_points.txt\"))\n\n        # write PEP 610 metadata\n        direct_url_json = dist_info.joinpath(\"direct_url.json\")\n        direct_url_json.write_text(\n            json.dumps(\n                {\n                    \"dir_info\": {\"editable\": True},\n                    \"url\": self._poetry.file.path.parent.absolute().as_uri(),\n                }\n            )\n        )\n        added_files.append(direct_url_json)\n\n        record = dist_info.joinpath(\"RECORD\")\n        with record.open(\"w\", encoding=\"utf-8\", newline=\"\") as f:\n            csv_writer = csv.writer(f)\n            for path in added_files:\n                hash = self._get_file_hash(path)\n                size = path.stat().st_size\n                csv_writer.writerow((path, f\"sha256={hash}\", size))\n\n            # RECORD itself is recorded with no hash or size\n            csv_writer.writerow((record, \"\", \"\"))\n\n    def _get_file_hash(self, filepath: Path) -> str:\n        hashsum = hashlib.sha256()\n        with filepath.open(\"rb\") as src:\n            while True:\n                buf = src.read(1024 * 8)\n                if not buf:\n                    break\n                hashsum.update(buf)\n\n            src.seek(0)\n\n        return urlsafe_b64encode(hashsum.digest()).decode(\"ascii\").rstrip(\"=\")\n\n    def _debug(self, msg: str) -> None:\n        if self._io.is_debug():\n            self._io.write_line(msg)\n", "path": "src/poetry/masonry/builders/editable.py"}], "after_files": [{"content": "from __future__ import annotations\n\nimport csv\nimport hashlib\nimport json\nimport os\n\nfrom base64 import urlsafe_b64encode\nfrom pathlib import Path\nfrom typing import TYPE_CHECKING\n\nfrom poetry.core.masonry.builders.builder import Builder\nfrom poetry.core.masonry.builders.sdist import SdistBuilder\nfrom poetry.core.masonry.utils.package_include import PackageInclude\n\nfrom poetry.utils._compat import WINDOWS\nfrom poetry.utils._compat import decode\nfrom poetry.utils.env import build_environment\nfrom poetry.utils.helpers import is_dir_writable\nfrom poetry.utils.pip import pip_install\n\n\nif TYPE_CHECKING:\n    from cleo.io.io import IO\n\n    from poetry.poetry import Poetry\n    from poetry.utils.env import Env\n\nSCRIPT_TEMPLATE = \"\"\"\\\n#!{python}\nimport sys\nfrom {module} import {callable_holder}\n\nif __name__ == '__main__':\n    sys.exit({callable_}())\n\"\"\"\n\nWINDOWS_CMD_TEMPLATE = \"\"\"\\\n@echo off\\r\\n\"{python}\" \"%~dp0\\\\{script}\" %*\\r\\n\n\"\"\"\n\n\nclass EditableBuilder(Builder):\n    def __init__(self, poetry: Poetry, env: Env, io: IO) -> None:\n        self._poetry: Poetry\n        super().__init__(poetry)\n\n        self._env = env\n        self._io = io\n\n    def build(self, target_dir: Path | None = None) -> Path:\n        self._debug(\n            f\"  - Building package <c1>{self._package.name}</c1> in\"\n            \" <info>editable</info> mode\"\n        )\n\n        if self._package.build_script:\n            if self._package.build_should_generate_setup():\n                self._debug(\n                    \"  - <warning>Falling back on using a <b>setup.py</b></warning>\"\n                )\n                self._setup_build()\n                path: Path = self._path\n                return path\n\n            self._run_build_script(self._package.build_script)\n\n        for removed in self._env.site_packages.remove_distribution_files(\n            distribution_name=self._package.name\n        ):\n            self._debug(\n                f\"  - Removed <c2>{removed.name}</c2> directory from\"\n                f\" <b>{removed.parent}</b>\"\n            )\n\n        added_files = []\n        added_files += self._add_pth()\n        added_files += self._add_scripts()\n        self._add_dist_info(added_files)\n\n        path = self._path\n        return path\n\n    def _run_build_script(self, build_script: str) -> None:\n        with build_environment(poetry=self._poetry, env=self._env, io=self._io) as env:\n            self._debug(f\"  - Executing build script: <b>{build_script}</b>\")\n            env.run(\"python\", str(self._path.joinpath(build_script)), call=True)\n\n    def _setup_build(self) -> None:\n        builder = SdistBuilder(self._poetry)\n        setup = self._path / \"setup.py\"\n        has_setup = setup.exists()\n\n        if has_setup:\n            self._io.write_error_line(\n                \"<warning>A setup.py file already exists. Using it.</warning>\"\n            )\n        else:\n            with setup.open(\"w\", encoding=\"utf-8\") as f:\n                f.write(decode(builder.build_setup()))\n\n        try:\n            pip_install(self._path, self._env, upgrade=True, editable=True)\n        finally:\n            if not has_setup:\n                os.remove(setup)\n\n    def _add_pth(self) -> list[Path]:\n        paths = {\n            include.base.resolve().as_posix()\n            for include in self._module.includes\n            if isinstance(include, PackageInclude)\n            and (include.is_module() or include.is_package())\n        }\n\n        content = \"\".join(decode(path + os.linesep) for path in paths)\n        pth_file = Path(self._module.name).with_suffix(\".pth\")\n\n        # remove any pre-existing pth files for this package\n        for file in self._env.site_packages.find(path=pth_file, writable_only=True):\n            self._debug(\n                f\"  - Removing existing <c2>{file.name}</c2> from <b>{file.parent}</b>\"\n                f\" for {self._poetry.file.path.parent}\"\n            )\n            file.unlink(missing_ok=True)\n\n        try:\n            pth_file = self._env.site_packages.write_text(\n                pth_file, content, encoding=\"utf-8\"\n            )\n            self._debug(\n                f\"  - Adding <c2>{pth_file.name}</c2> to <b>{pth_file.parent}</b> for\"\n                f\" {self._poetry.file.path.parent}\"\n            )\n            return [pth_file]\n        except OSError:\n            # TODO: Replace with PermissionError\n            self._io.write_error_line(\n                f\"  - Failed to create <c2>{pth_file.name}</c2> for\"\n                f\" {self._poetry.file.path.parent}\"\n            )\n            return []\n\n    def _add_scripts(self) -> list[Path]:\n        added = []\n        entry_points = self.convert_entry_points()\n\n        for scripts_path in self._env.script_dirs:\n            if is_dir_writable(path=scripts_path, create=True):\n                break\n        else:\n            self._io.write_error_line(\n                \"  - Failed to find a suitable script installation directory for\"\n                f\" {self._poetry.file.path.parent}\"\n            )\n            return []\n\n        scripts = entry_points.get(\"console_scripts\", [])\n        for script in scripts:\n            name, script = script.split(\" = \")\n            module, callable_ = script.split(\":\")\n            callable_holder = callable_.split(\".\", 1)[0]\n\n            script_file = scripts_path.joinpath(name)\n            self._debug(\n                f\"  - Adding the <c2>{name}</c2> script to <b>{scripts_path}</b>\"\n            )\n            with script_file.open(\"w\", encoding=\"utf-8\") as f:\n                f.write(\n                    decode(\n                        SCRIPT_TEMPLATE.format(\n                            python=self._env.python,\n                            module=module,\n                            callable_holder=callable_holder,\n                            callable_=callable_,\n                        )\n                    )\n                )\n\n            script_file.chmod(0o755)\n\n            added.append(script_file)\n\n            if WINDOWS:\n                cmd_script = script_file.with_suffix(\".cmd\")\n                cmd = WINDOWS_CMD_TEMPLATE.format(python=self._env.python, script=name)\n                self._debug(\n                    f\"  - Adding the <c2>{cmd_script.name}</c2> script wrapper to\"\n                    f\" <b>{scripts_path}</b>\"\n                )\n\n                with cmd_script.open(\"w\", encoding=\"utf-8\") as f:\n                    f.write(decode(cmd))\n\n                added.append(cmd_script)\n\n        return added\n\n    def _add_dist_info(self, added_files: list[Path]) -> None:\n        from poetry.core.masonry.builders.wheel import WheelBuilder\n\n        added_files = added_files[:]\n\n        builder = WheelBuilder(self._poetry)\n        dist_info = self._env.site_packages.mkdir(Path(builder.dist_info))\n\n        self._debug(\n            f\"  - Adding the <c2>{dist_info.name}</c2> directory to\"\n            f\" <b>{dist_info.parent}</b>\"\n        )\n\n        with dist_info.joinpath(\"METADATA\").open(\"w\", encoding=\"utf-8\") as f:\n            builder._write_metadata_file(f)\n\n        added_files.append(dist_info.joinpath(\"METADATA\"))\n\n        with dist_info.joinpath(\"INSTALLER\").open(\"w\", encoding=\"utf-8\") as f:\n            f.write(\"poetry\")\n\n        added_files.append(dist_info.joinpath(\"INSTALLER\"))\n\n        if self.convert_entry_points():\n            with dist_info.joinpath(\"entry_points.txt\").open(\n                \"w\", encoding=\"utf-8\"\n            ) as f:\n                builder._write_entry_points(f)\n\n            added_files.append(dist_info.joinpath(\"entry_points.txt\"))\n\n        # write PEP 610 metadata\n        direct_url_json = dist_info.joinpath(\"direct_url.json\")\n        direct_url_json.write_text(\n            json.dumps(\n                {\n                    \"dir_info\": {\"editable\": True},\n                    \"url\": self._poetry.file.path.parent.absolute().as_uri(),\n                }\n            )\n        )\n        added_files.append(direct_url_json)\n\n        record = dist_info.joinpath(\"RECORD\")\n        with record.open(\"w\", encoding=\"utf-8\", newline=\"\") as f:\n            csv_writer = csv.writer(f)\n            for path in added_files:\n                hash = self._get_file_hash(path)\n                size = path.stat().st_size\n                csv_writer.writerow((path, f\"sha256={hash}\", size))\n\n            # RECORD itself is recorded with no hash or size\n            csv_writer.writerow((record, \"\", \"\"))\n\n    def _get_file_hash(self, filepath: Path) -> str:\n        hashsum = hashlib.sha256()\n        with filepath.open(\"rb\") as src:\n            while True:\n                buf = src.read(1024 * 8)\n                if not buf:\n                    break\n                hashsum.update(buf)\n\n            src.seek(0)\n\n        return urlsafe_b64encode(hashsum.digest()).decode(\"ascii\").rstrip(\"=\")\n\n    def _debug(self, msg: str) -> None:\n        if self._io.is_debug():\n            self._io.write_line(msg)\n", "path": "src/poetry/masonry/builders/editable.py"}]}