|
4 | 4 | # This plugin was not named "cache" to avoid conflicts with the external |
5 | 5 | # pytest-cache version. |
6 | 6 | import dataclasses |
| 7 | +import errno |
7 | 8 | import json |
8 | 9 | import os |
9 | 10 | from pathlib import Path |
@@ -227,14 +228,24 @@ def _ensure_cache_dir_and_supporting_files(self) -> None: |
227 | 228 | with open(path.joinpath("CACHEDIR.TAG"), "xb") as f: |
228 | 229 | f.write(CACHEDIR_TAG_CONTENT) |
229 | 230 |
|
230 | | - path.rename(self._cachedir) |
231 | | - # Create a directory in place of the one we just moved so that `TemporaryDirectory`'s |
232 | | - # cleanup doesn't complain. |
233 | | - # |
234 | | - # TODO: pass ignore_cleanup_errors=True when we no longer support python < 3.10. See |
235 | | - # https://github.com/python/cpython/issues/74168. Note that passing delete=False would |
236 | | - # do the wrong thing in case of errors and isn't supported until python 3.12. |
237 | | - path.mkdir() |
| 231 | + try: |
| 232 | + path.rename(self._cachedir) |
| 233 | + except OSError as e: |
| 234 | + # If 2 concurrent pytests both race to the rename, the loser |
| 235 | + # gets "Directory not empty" from the rename. In this case, |
| 236 | + # everything is handled so just continue (while letting the |
| 237 | + # temporary directory be cleaned up). |
| 238 | + if e.errno != errno.ENOTEMPTY: |
| 239 | + raise |
| 240 | + else: |
| 241 | + # Create a directory in place of the one we just moved so that |
| 242 | + # `TemporaryDirectory`'s cleanup doesn't complain. |
| 243 | + # |
| 244 | + # TODO: pass ignore_cleanup_errors=True when we no longer support python < 3.10. |
| 245 | + # See https://github.com/python/cpython/issues/74168. Note that passing |
| 246 | + # delete=False would do the wrong thing in case of errors and isn't supported |
| 247 | + # until python 3.12. |
| 248 | + path.mkdir() |
238 | 249 |
|
239 | 250 |
|
240 | 251 | class LFPluginCollWrapper: |
|
0 commit comments