[Python-checkins] bpo-10496: distutils check_environ() handles getpwuid() error (GH-10931)

Victor Stinner webhook-mailer at python.org
Tue Dec 18 10:18:10 EST 2018


https://github.com/python/cpython/commit/17d0c0595e101c4ce76b58e55de37e6b5083e6cd
commit: 17d0c0595e101c4ce76b58e55de37e6b5083e6cd
branch: master
author: Victor Stinner <vstinner at redhat.com>
committer: GitHub <noreply at github.com>
date: 2018-12-18T16:17:56+01:00
summary:

bpo-10496: distutils check_environ() handles getpwuid() error (GH-10931)

check_environ() of distutils.utils now catchs KeyError on calling
pwd.getpwuid(): don't create the HOME environment variable in this
case.

files:
A Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst
M Lib/distutils/tests/test_util.py
M Lib/distutils/util.py

diff --git a/Lib/distutils/tests/test_util.py b/Lib/distutils/tests/test_util.py
index e2fc3809587f..bf0d4333f9ae 100644
--- a/Lib/distutils/tests/test_util.py
+++ b/Lib/distutils/tests/test_util.py
@@ -4,6 +4,7 @@
 import unittest
 from copy import copy
 from test.support import run_unittest
+from unittest import mock
 
 from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError
 from distutils.util import (get_platform, convert_path, change_root,
@@ -234,20 +235,35 @@ def _join(*path):
 
     def test_check_environ(self):
         util._environ_checked = 0
-        if 'HOME' in os.environ:
-            del os.environ['HOME']
+        os.environ.pop('HOME', None)
 
-        # posix without HOME
-        if os.name == 'posix':  # this test won't run on windows
-            check_environ()
-            import pwd
-            self.assertEqual(os.environ['HOME'], pwd.getpwuid(os.getuid())[5])
-        else:
-            check_environ()
+        check_environ()
 
         self.assertEqual(os.environ['PLAT'], get_platform())
         self.assertEqual(util._environ_checked, 1)
 
+    @unittest.skipUnless(os.name == 'posix', 'specific to posix')
+    def test_check_environ_getpwuid(self):
+        util._environ_checked = 0
+        os.environ.pop('HOME', None)
+
+        import pwd
+
+        # only set pw_dir field, other fields are not used
+        result = pwd.struct_passwd((None, None, None, None, None,
+                                    '/home/distutils', None))
+        with mock.patch.object(pwd, 'getpwuid', return_value=result):
+            check_environ()
+            self.assertEqual(os.environ['HOME'], '/home/distutils')
+
+        util._environ_checked = 0
+        os.environ.pop('HOME', None)
+
+        # bpo-10496: Catch pwd.getpwuid() error
+        with mock.patch.object(pwd, 'getpwuid', side_effect=KeyError):
+            check_environ()
+            self.assertNotIn('HOME', os.environ)
+
     def test_split_quoted(self):
         self.assertEqual(split_quoted('""one"" "two" \'three\' \\four'),
                          ['one', 'two', 'three', 'four'])
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
index 83682628ba68..30a21e4afa1f 100644
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -157,8 +157,13 @@ def check_environ ():
         return
 
     if os.name == 'posix' and 'HOME' not in os.environ:
-        import pwd
-        os.environ['HOME'] = pwd.getpwuid(os.getuid())[5]
+        try:
+            import pwd
+            os.environ['HOME'] = pwd.getpwuid(os.getuid())[5]
+        except (ImportError, KeyError):
+            # bpo-10496: if the current user identifier doesn't exist in the
+            # password database, do nothing
+            pass
 
     if 'PLAT' not in os.environ:
         os.environ['PLAT'] = get_platform()
diff --git a/Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst b/Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst
new file mode 100644
index 000000000000..cbfe5eb11668
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst
@@ -0,0 +1,3 @@
+:func:`~distutils.utils.check_environ` of :mod:`distutils.utils` now catchs
+:exc:`KeyError` on calling :func:`pwd.getpwuid`: don't create the ``HOME``
+environment variable in this case.



More information about the Python-checkins mailing list