diff --git a/news/5210.bugfix.rst b/news/5210.bugfix.rst new file mode 100644 index 0000000000..e4f8caef4e --- /dev/null +++ b/news/5210.bugfix.rst @@ -0,0 +1,2 @@ +Write output from ``subprocess_run`` directly to ``stdout`` instead of creating temporary file. +Remove deprecated ``distutils.sysconfig``, use ``sysconfig``. diff --git a/pipenv/environment.py b/pipenv/environment.py index ed0d856ef9..36016bbb85 100644 --- a/pipenv/environment.py +++ b/pipenv/environment.py @@ -342,36 +342,28 @@ def build_command( pylib_lines = [] pyinc_lines = [] py_command = ( - "import sysconfig, distutils.sysconfig, io, json, sys; paths = {{" - "%s }}; value = u'{{0}}'.format(json.dumps(paths));" - "fh = io.open('{0}', 'w'); fh.write(value); fh.close()" + "import sysconfig, json; paths = {%s};" + "value = u'{0}'.format(json.dumps(paths)); print(value)" ) - distutils_line = "distutils.sysconfig.get_python_{0}(plat_specific={1})" sysconfig_line = "sysconfig.get_path('{0}')" if python_lib: - for key, var, val in (("pure", "lib", "0"), ("plat", "lib", "1")): - dist_prefix = f"{key}lib" - # XXX: We need to get 'stdlib' or 'platstdlib' - sys_prefix = "{}stdlib".format("" if key == "pure" else key) + for key in ("purelib", "platlib", "stdlib", "platstdlib"): pylib_lines.append( - f"u'{dist_prefix}': u'{{{{0}}}}'.format({distutils_line.format(var, val)})" - ) - pylib_lines.append( - f"u'{sys_prefix}': u'{{{{0}}}}'.format({sysconfig_line.format(sys_prefix)})" + f"u'{key}': u'{{0}}'.format({sysconfig_line.format(key)})" ) if python_inc: - for key, var, val in (("include", "inc", "0"), ("platinclude", "inc", "1")): - pylib_lines.append( - f"u'{key}': u'{{{{0}}}}'.format({distutils_line.format(var, val)})" + for key in ("include", "platinclude"): + pyinc_lines.append( + f"u'{key}': u'{{0}}'.format({sysconfig_line.format(key)})" ) lines = pylib_lines + pyinc_lines if scripts: lines.append( - "u'scripts': u'{{0}}'.format(%s)" % sysconfig_line.format("scripts") + "u'scripts': u'{0}'.format(%s)" % sysconfig_line.format("scripts") ) if py_version: lines.append( - "u'py_version_short': u'{{0}}'.format(distutils.sysconfig.get_python_version())," + "u'py_version_short': u'{0}'.format(sysconfig.get_python_version())," ) lines_as_str = ",".join(lines) py_command = py_command % lines_as_str @@ -384,18 +376,13 @@ def get_paths(self) -> Optional[Dict[str, str]]: :return: The python paths for the environment :rtype: Dict[str, str] """ - tmpfile = vistir.path.create_tracked_tempfile(suffix=".json") - tmpfile.close() - tmpfile_path = make_posix(tmpfile.name) py_command = self.build_command( python_lib=True, python_inc=True, scripts=True, py_version=True ) - command = [self.python, "-c", py_command.format(tmpfile_path)] + command = [self.python, "-c", py_command] c = subprocess_run(command) if c.returncode == 0: - paths = {} - with open(tmpfile_path, "r", encoding="utf-8") as fh: - paths = json.load(fh) + paths = json.loads(c.stdout) if "purelib" in paths: paths["libdir"] = paths["purelib"] = make_posix(paths["purelib"]) for key in ( @@ -420,17 +407,12 @@ def get_lib_paths(self) -> Dict[str, str]: :return: The python include path for the environment :rtype: Dict[str, str] """ - tmpfile = vistir.path.create_tracked_tempfile(suffix=".json") - tmpfile.close() - tmpfile_path = make_posix(tmpfile.name) py_command = self.build_command(python_lib=True) - command = [self.python, "-c", py_command.format(tmpfile_path)] + command = [self.python, "-c", py_command] c = subprocess_run(command) paths = None if c.returncode == 0: - paths = {} - with open(tmpfile_path, "r", encoding="utf-8") as fh: - paths = json.load(fh) + paths = json.loads(c.stdout) if "purelib" in paths: paths["libdir"] = paths["purelib"] = make_posix(paths["purelib"]) for key in ("platlib", "platstdlib", "stdlib"): @@ -476,22 +458,11 @@ def get_include_path(self) -> Optional[Dict[str, str]]: :return: The python include path for the environment :rtype: Dict[str, str] """ - tmpfile = vistir.path.create_tracked_tempfile(suffix=".json") - tmpfile.close() - tmpfile_path = make_posix(tmpfile.name) - py_command = ( - "import distutils.sysconfig, io, json, sys; paths = {{u'include': " - "u'{{0}}'.format(distutils.sysconfig.get_python_inc(plat_specific=0)), " - "u'platinclude': u'{{0}}'.format(distutils.sysconfig.get_python_inc(" - "plat_specific=1)) }}; value = u'{{0}}'.format(json.dumps(paths));" - "fh = io.open('{0}', 'w'); fh.write(value); fh.close()" - ) - command = [self.python, "-c", py_command.format(tmpfile_path)] + py_command = self.build_command(python_inc=True) + command = [self.python, "-c", py_command] c = subprocess_run(command) if c.returncode == 0: - paths = [] - with open(tmpfile_path, "r", encoding="utf-8") as fh: - paths = json.load(fh) + paths = json.loads(c.stdout) for key in ("include", "platinclude"): if key in paths: paths[key] = make_posix(paths[key])