203 def _generate_names(cls, name: str) -> Generator[str, None, None]:
204 """Generates a series of temporary names.
206 The algorithm replaces the leading characters in the name
207 with ones that are valid filesystem characters, but are not
208 valid package names (for both Python and pip definitions of
211 for i in range(1, len(name)):
212 for candidate in itertools.combinations_with_replacement(
213 cls.LEADING_CHARS, i - 1
215 new_name = "~" + "".join(candidate) + name[i:]
219 # If we make it this far, we will have to make a longer name
220 for i in range(len(cls.LEADING_CHARS)):
221 for candidate in itertools.combinations_with_replacement(
224 new_name = "~" + "".join(candidate) + name
228 def _create(self, kind: str) -> str:
229 root, name = os.path.split(self.original)
230 for candidate in self._generate_names(name):
231 path = os.path.join(root, candidate)
234 except OSError as ex:
235 # Continue if the name exists already
236 if ex.errno != errno.EEXIST:
239 path = os.path.realpath(path)
242 # Final fallback on the default behavior.
243 path = os.path.realpath(tempfile.mkdtemp(prefix=f"pip-{kind}-"))
245 logger.debug("Created temporary directory: %s", path)