We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Poetry fails to install p4python due to read-only files
<!--
  Hi there! Thank you for discovering and submitting an issue.

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

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

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

- **OS version and name**: Windows 10
- **Poetry version**: poetry 0.12.2
- **Link of a [pyproject.toml Gist](https://gist.github.com/epage/5f28e3b1e5eeb9a30697363e369a5fde)
- **Link of a [backtrace Gist](https://gist.github.com/epage/2584ad981ff5d9f175d55212b0192987)

## Issue

In digging into the problem, it seems that p4python's files are all marked read-only, causing windows to error when trying to delete them via `shutil.rmtree` which is invoked by poetry's custom temp directory handling.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `poetry/utils/helpers.py`
Content:
```
1 import os
2 import re
3 import shutil
4 import stat
5 import tempfile
6 
7 from contextlib import contextmanager
8 from typing import List
9 from typing import Optional
10 
11 from poetry.config.config import Config
12 from poetry.utils._compat import Path
13 from poetry.version import Version
14 
15 
16 try:
17     from collections.abc import Mapping
18 except ImportError:
19     from collections import Mapping
20 
21 
22 _canonicalize_regex = re.compile("[-_]+")
23 
24 
25 def canonicalize_name(name):  # type: (str) -> str
26     return _canonicalize_regex.sub("-", name).lower()
27 
28 
29 def module_name(name):  # type: (str) -> str
30     return canonicalize_name(name).replace(".", "_").replace("-", "_")
31 
32 
33 def normalize_version(version):  # type: (str) -> str
34     return str(Version(version))
35 
36 
37 @contextmanager
38 def temporary_directory(*args, **kwargs):
39     try:
40         from tempfile import TemporaryDirectory
41 
42         with TemporaryDirectory(*args, **kwargs) as name:
43             yield name
44     except ImportError:
45         name = tempfile.mkdtemp(*args, **kwargs)
46 
47         yield name
48 
49         shutil.rmtree(name)
50 
51 
52 def parse_requires(requires):  # type: (str) -> List[str]
53     lines = requires.split("\n")
54 
55     requires_dist = []
56     in_section = False
57     current_marker = None
58     for line in lines:
59         line = line.strip()
60         if not line:
61             if in_section:
62                 in_section = False
63 
64             continue
65 
66         if line.startswith("["):
67             # extras or conditional dependencies
68             marker = line.lstrip("[").rstrip("]")
69             if ":" not in marker:
70                 extra, marker = marker, None
71             else:
72                 extra, marker = marker.split(":")
73 
74             if extra:
75                 if marker:
76                     marker = '{} and extra == "{}"'.format(marker, extra)
77                 else:
78                     marker = 'extra == "{}"'.format(extra)
79 
80             if marker:
81                 current_marker = marker
82 
83             continue
84 
85         if current_marker:
86             line = "{} ; {}".format(line, current_marker)
87 
88         requires_dist.append(line)
89 
90     return requires_dist
91 
92 
93 def get_cert(config, repository_name):  # type: (Config, str) -> Optional[Path]
94     cert = config.get("certificates.{}.cert".format(repository_name))
95     if cert:
96         return Path(cert)
97     else:
98         return None
99 
100 
101 def get_client_cert(config, repository_name):  # type: (Config, str) -> Optional[Path]
102     client_cert = config.get("certificates.{}.client-cert".format(repository_name))
103     if client_cert:
104         return Path(client_cert)
105     else:
106         return None
107 
108 
109 def _on_rm_error(func, path, exc_info):
110     if not os.path.exists(path):
111         return
112 
113     os.chmod(path, stat.S_IWRITE)
114     func(path)
115 
116 
117 def safe_rmtree(path):
118     if Path(path).is_symlink():
119         return os.unlink(str(path))
120 
121     shutil.rmtree(path, onerror=_on_rm_error)
122 
123 
124 def merge_dicts(d1, d2):
125     for k, v in d2.items():
126         if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], Mapping):
127             merge_dicts(d1[k], d2[k])
128         else:
129             d1[k] = d2[k]
130
```
--- END FILES ---

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

Here is an example:

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

```

diff --git a/poetry/utils/helpers.py b/poetry/utils/helpers.py
--- a/poetry/utils/helpers.py
+++ b/poetry/utils/helpers.py
@@ -34,19 +34,18 @@
     return str(Version(version))
 
 
+def _del_ro(action, name, exc):
+    os.chmod(name, stat.S_IWRITE)
+    os.remove(name)
+
+
 @contextmanager
 def temporary_directory(*args, **kwargs):
-    try:
-        from tempfile import TemporaryDirectory
-
-        with TemporaryDirectory(*args, **kwargs) as name:
-            yield name
-    except ImportError:
-        name = tempfile.mkdtemp(*args, **kwargs)
+    name = tempfile.mkdtemp(*args, **kwargs)
 
-        yield name
+    yield name
 
-        shutil.rmtree(name)
+    shutil.rmtree(name, onerror=_del_ro)
 
 
 def parse_requires(requires):  # type: (str) -> List[str]

{"golden_diff": "diff --git a/poetry/utils/helpers.py b/poetry/utils/helpers.py\n--- a/poetry/utils/helpers.py\n+++ b/poetry/utils/helpers.py\n@@ -34,19 +34,18 @@\n     return str(Version(version))\n \n \n+def _del_ro(action, name, exc):\n+    os.chmod(name, stat.S_IWRITE)\n+    os.remove(name)\n+\n+\n @contextmanager\n def temporary_directory(*args, **kwargs):\n-    try:\n-        from tempfile import TemporaryDirectory\n-\n-        with TemporaryDirectory(*args, **kwargs) as name:\n-            yield name\n-    except ImportError:\n-        name = tempfile.mkdtemp(*args, **kwargs)\n+    name = tempfile.mkdtemp(*args, **kwargs)\n \n-        yield name\n+    yield name\n \n-        shutil.rmtree(name)\n+    shutil.rmtree(name, onerror=_del_ro)\n \n \n def parse_requires(requires):  # type: (str) -> List[str]\n", "issue": "Poetry fails to install p4python due to read-only files\n<!--\r\n  Hi there! Thank you for discovering and submitting an issue.\r\n\r\n  Before you submit this; let's make sure of a few things.\r\n  Please make sure the following boxes are ticked if they are correct.\r\n  If not, please try and fulfill these first.\r\n-->\r\n\r\n<!-- Checked checkbox should look like this: [x] -->\r\n- [x] I am on the [latest](https://github.com/sdispater/poetry/releases/latest) Poetry version.\r\n- [x] I have searched the [issues](https://github.com/sdispater/poetry/issues) of this repo and believe that this is not a duplicate.\r\n- [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option).\r\n\r\n<!--\r\n  Once those are done, if you're able to fill in the following list with your information,\r\n  it'd be very helpful to whoever handles the issue.\r\n-->\r\n\r\n- **OS version and name**: Windows 10\r\n- **Poetry version**: poetry 0.12.2\r\n- **Link of a [pyproject.toml Gist](https://gist.github.com/epage/5f28e3b1e5eeb9a30697363e369a5fde)\r\n- **Link of a [backtrace Gist](https://gist.github.com/epage/2584ad981ff5d9f175d55212b0192987)\r\n\r\n## Issue\r\n\r\nIn digging into the problem, it seems that p4python's files are all marked read-only, causing windows to error when trying to delete them via `shutil.rmtree` which is invoked by poetry's custom temp directory handling.\n", "before_files": [{"content": "import os\nimport re\nimport shutil\nimport stat\nimport tempfile\n\nfrom contextlib import contextmanager\nfrom typing import List\nfrom typing import Optional\n\nfrom poetry.config.config import Config\nfrom poetry.utils._compat import Path\nfrom poetry.version import Version\n\n\ntry:\n    from collections.abc import Mapping\nexcept ImportError:\n    from collections import Mapping\n\n\n_canonicalize_regex = re.compile(\"[-_]+\")\n\n\ndef canonicalize_name(name):  # type: (str) -> str\n    return _canonicalize_regex.sub(\"-\", name).lower()\n\n\ndef module_name(name):  # type: (str) -> str\n    return canonicalize_name(name).replace(\".\", \"_\").replace(\"-\", \"_\")\n\n\ndef normalize_version(version):  # type: (str) -> str\n    return str(Version(version))\n\n\n@contextmanager\ndef temporary_directory(*args, **kwargs):\n    try:\n        from tempfile import TemporaryDirectory\n\n        with TemporaryDirectory(*args, **kwargs) as name:\n            yield name\n    except ImportError:\n        name = tempfile.mkdtemp(*args, **kwargs)\n\n        yield name\n\n        shutil.rmtree(name)\n\n\ndef parse_requires(requires):  # type: (str) -> List[str]\n    lines = requires.split(\"\\n\")\n\n    requires_dist = []\n    in_section = False\n    current_marker = None\n    for line in lines:\n        line = line.strip()\n        if not line:\n            if in_section:\n                in_section = False\n\n            continue\n\n        if line.startswith(\"[\"):\n            # extras or conditional dependencies\n            marker = line.lstrip(\"[\").rstrip(\"]\")\n            if \":\" not in marker:\n                extra, marker = marker, None\n            else:\n                extra, marker = marker.split(\":\")\n\n            if extra:\n                if marker:\n                    marker = '{} and extra == \"{}\"'.format(marker, extra)\n                else:\n                    marker = 'extra == \"{}\"'.format(extra)\n\n            if marker:\n                current_marker = marker\n\n            continue\n\n        if current_marker:\n            line = \"{} ; {}\".format(line, current_marker)\n\n        requires_dist.append(line)\n\n    return requires_dist\n\n\ndef get_cert(config, repository_name):  # type: (Config, str) -> Optional[Path]\n    cert = config.get(\"certificates.{}.cert\".format(repository_name))\n    if cert:\n        return Path(cert)\n    else:\n        return None\n\n\ndef get_client_cert(config, repository_name):  # type: (Config, str) -> Optional[Path]\n    client_cert = config.get(\"certificates.{}.client-cert\".format(repository_name))\n    if client_cert:\n        return Path(client_cert)\n    else:\n        return None\n\n\ndef _on_rm_error(func, path, exc_info):\n    if not os.path.exists(path):\n        return\n\n    os.chmod(path, stat.S_IWRITE)\n    func(path)\n\n\ndef safe_rmtree(path):\n    if Path(path).is_symlink():\n        return os.unlink(str(path))\n\n    shutil.rmtree(path, onerror=_on_rm_error)\n\n\ndef merge_dicts(d1, d2):\n    for k, v in d2.items():\n        if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], Mapping):\n            merge_dicts(d1[k], d2[k])\n        else:\n            d1[k] = d2[k]\n", "path": "poetry/utils/helpers.py"}], "after_files": [{"content": "import os\nimport re\nimport shutil\nimport stat\nimport tempfile\n\nfrom contextlib import contextmanager\nfrom typing import List\nfrom typing import Optional\n\nfrom poetry.config.config import Config\nfrom poetry.utils._compat import Path\nfrom poetry.version import Version\n\n\ntry:\n    from collections.abc import Mapping\nexcept ImportError:\n    from collections import Mapping\n\n\n_canonicalize_regex = re.compile(\"[-_]+\")\n\n\ndef canonicalize_name(name):  # type: (str) -> str\n    return _canonicalize_regex.sub(\"-\", name).lower()\n\n\ndef module_name(name):  # type: (str) -> str\n    return canonicalize_name(name).replace(\".\", \"_\").replace(\"-\", \"_\")\n\n\ndef normalize_version(version):  # type: (str) -> str\n    return str(Version(version))\n\n\ndef _del_ro(action, name, exc):\n    os.chmod(name, stat.S_IWRITE)\n    os.remove(name)\n\n\n@contextmanager\ndef temporary_directory(*args, **kwargs):\n    name = tempfile.mkdtemp(*args, **kwargs)\n\n    yield name\n\n    shutil.rmtree(name, onerror=_del_ro)\n\n\ndef parse_requires(requires):  # type: (str) -> List[str]\n    lines = requires.split(\"\\n\")\n\n    requires_dist = []\n    in_section = False\n    current_marker = None\n    for line in lines:\n        line = line.strip()\n        if not line:\n            if in_section:\n                in_section = False\n\n            continue\n\n        if line.startswith(\"[\"):\n            # extras or conditional dependencies\n            marker = line.lstrip(\"[\").rstrip(\"]\")\n            if \":\" not in marker:\n                extra, marker = marker, None\n            else:\n                extra, marker = marker.split(\":\")\n\n            if extra:\n                if marker:\n                    marker = '{} and extra == \"{}\"'.format(marker, extra)\n                else:\n                    marker = 'extra == \"{}\"'.format(extra)\n\n            if marker:\n                current_marker = marker\n\n            continue\n\n        if current_marker:\n            line = \"{} ; {}\".format(line, current_marker)\n\n        requires_dist.append(line)\n\n    return requires_dist\n\n\ndef get_cert(config, repository_name):  # type: (Config, str) -> Optional[Path]\n    cert = config.get(\"certificates.{}.cert\".format(repository_name))\n    if cert:\n        return Path(cert)\n    else:\n        return None\n\n\ndef get_client_cert(config, repository_name):  # type: (Config, str) -> Optional[Path]\n    client_cert = config.get(\"certificates.{}.client-cert\".format(repository_name))\n    if client_cert:\n        return Path(client_cert)\n    else:\n        return None\n\n\ndef _on_rm_error(func, path, exc_info):\n    if not os.path.exists(path):\n        return\n\n    os.chmod(path, stat.S_IWRITE)\n    func(path)\n\n\ndef safe_rmtree(path):\n    if Path(path).is_symlink():\n        return os.unlink(str(path))\n\n    shutil.rmtree(path, onerror=_on_rm_error)\n\n\ndef merge_dicts(d1, d2):\n    for k, v in d2.items():\n        if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], Mapping):\n            merge_dicts(d1[k], d2[k])\n        else:\n            d1[k] = d2[k]\n", "path": "poetry/utils/helpers.py"}]}