bpo-46933: Make pwd module optional (GH-31700)

Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>
This commit is contained in:
Christian Heimes 2022-03-07 14:36:47 +02:00 committed by GitHub
parent 3b3be05a16
commit ca9689f8da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 496 additions and 560 deletions

1
.gitignore vendored
View file

@ -75,6 +75,7 @@ Mac/pythonw
Misc/python.pc
Misc/python-embed.pc
Misc/python-config.sh
Modules/Setup.bootstrap
Modules/Setup.config
Modules/Setup.local
Modules/Setup.stdlib

View file

@ -248,7 +248,10 @@ def test_check_environ_getpwuid(self):
util._environ_checked = 0
os.environ.pop('HOME', None)
import pwd
try:
import pwd
except ImportError:
raise unittest.SkipTest("Test requires pwd module.")
# only set pw_dir field, other fields are not used
result = pwd.struct_passwd((None, None, None, None, None,

View file

@ -241,7 +241,11 @@ def expanduser(path):
i = len(path)
if i == 1:
if 'HOME' not in os.environ:
import pwd
try:
import pwd
except ImportError:
# pwd module unavailable, return path unchanged
return path
try:
userhome = pwd.getpwuid(os.getuid()).pw_dir
except KeyError:
@ -251,7 +255,11 @@ def expanduser(path):
else:
userhome = os.environ['HOME']
else:
import pwd
try:
import pwd
except ImportError:
# pwd module unavailable, return path unchanged
return path
name = path[1:i]
if isinstance(name, bytes):
name = str(name, 'ASCII')

View file

@ -1486,6 +1486,9 @@ def _test_home(self, p):
self.assertIs(type(p), type(q))
self.assertTrue(p.is_absolute())
@unittest.skipIf(
pwd is None, reason="Test requires pwd module to get homedir."
)
def test_home(self):
with os_helper.EnvironmentVarGuard() as env:
self._test_home(self.cls.home())

View file

@ -15,7 +15,6 @@
import time
import os
import platform
import pwd
import stat
import tempfile
import unittest
@ -23,6 +22,11 @@
import textwrap
from contextlib import contextmanager
try:
import pwd
except ImportError:
pwd = None
_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
os_helper.TESTFN + '-dummy-symlink')
@ -126,6 +130,7 @@ def test_setresgid_exception(self):
@unittest.skipUnless(hasattr(posix, 'initgroups'),
"test needs os.initgroups()")
@unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
def test_initgroups(self):
# It takes a string and an integer; check that it raises a TypeError
# for other argument lists.

View file

@ -917,6 +917,9 @@ Modules/Setup.local:
@# Create empty Setup.local when file was deleted by user
echo "# Edit this file for local setup changes" > $@
Modules/Setup.bootstrap: $(srcdir)/Modules/Setup.bootstrap.in config.status
./config.status $@
Modules/Setup.stdlib: $(srcdir)/Modules/Setup.stdlib.in config.status
./config.status $@
@ -925,13 +928,13 @@ Makefile Modules/config.c: Makefile.pre \
$(MAKESETUP) \
$(srcdir)/Modules/Setup \
Modules/Setup.local \
$(srcdir)/Modules/Setup.bootstrap \
Modules/Setup.bootstrap \
Modules/Setup.stdlib
$(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \
-s Modules \
Modules/Setup.local \
@MODULES_SETUP_STDLIB@ \
$(srcdir)/Modules/Setup.bootstrap \
Modules/Setup.bootstrap \
$(srcdir)/Modules/Setup
@mv config.c Modules
@echo "The Makefile was updated, you may need to re-run make."
@ -2146,7 +2149,7 @@ libainstall: @DEF_MAKE_RULE@ python-config
$(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in
$(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile
$(INSTALL_DATA) $(srcdir)/Modules/Setup $(DESTDIR)$(LIBPL)/Setup
$(INSTALL_DATA) $(srcdir)/Modules/Setup.bootstrap $(DESTDIR)$(LIBPL)/Setup.bootstrap
$(INSTALL_DATA) Modules/Setup.bootstrap $(DESTDIR)$(LIBPL)/Setup.bootstrap
$(INSTALL_DATA) Modules/Setup.stdlib $(DESTDIR)$(LIBPL)/Setup.stdlib
$(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local
$(INSTALL_DATA) Misc/python.pc $(DESTDIR)$(LIBPC)/python-$(VERSION).pc
@ -2381,8 +2384,9 @@ distclean: clobber
for file in $(srcdir)/Lib/test/data/* ; do \
if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \
done
-rm -f core Makefile Makefile.pre config.status Modules/Setup.local \
Modules/Setup.stdlib Modules/ld_so_aix Modules/python.exp Misc/python.pc \
-rm -f core Makefile Makefile.pre config.status Modules/Setup.local
Modules/Setup.bootstrap Modules/Setup.stdlib \
Modules/ld_so_aix Modules/python.exp Misc/python.pc \
Misc/python-embed.pc Misc/python-config.sh
-rm -f python*-gdb.py
# Issue #28258: set LC_ALL to avoid issues with Estonian locale.

View file

@ -0,0 +1 @@
The :mod:`pwd` module is now optional. :func:`os.path.expanduser` returns the path when the :mod:`pwd` module is not available.

View file

@ -32,4 +32,4 @@ _stat _stat.c
_symtable symtablemodule.c
# for systems without $HOME env, used by site._getuserbase()
pwd pwdmodule.c
@MODULE_PWD_TRUE@pwd pwdmodule.c

879
configure generated vendored

File diff suppressed because it is too large Load diff

View file

@ -4153,7 +4153,7 @@ AC_CHECK_FUNCS([ \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
getgrnam_r getgrouplist getgroups getitimer getloadavg getlogin \
getpeername getpgid getpid getppid getpriority _getpty \
getpwent getpwnam_r getpwuid_r getresgid getresuid getrusage getsid getspent \
getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
@ -6369,62 +6369,72 @@ AS_VAR_IF([TEST_MODULES], [yes],
)
AC_SUBST(TEST_MODULES)
AC_DEFUN([PY_STDLIB_MOD_SET_NA], [
m4_foreach([mod], [$@], [
AS_VAR_SET([py_cv_module_]mod, [n/a])])
])
# stdlib not available
dnl Modules that are not available on some platforms
dnl AIX has shadow passwords, but access is not via getspent()
dnl VxWorks does not provide crypt() function
AS_CASE([$ac_sys_system/$ac_sys_emscripten_target],
[AIX/*], [py_stdlib_not_available="_scproxy spwd"],
[VxWorks*/*], [py_stdlib_not_available="_scproxy _crypt termios grp"],
[Darwin/*], [py_stdlib_not_available="ossaudiodev spwd"],
[CYGWIN*/*], [py_stdlib_not_available="_scproxy nis"],
[QNX*/*], [py_stdlib_not_available="_scproxy nis"],
[FreeBSD*/*], [py_stdlib_not_available="_scproxy spwd"],
[AIX/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [spwd])],
[VxWorks*/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [_crypt], [termios], [grp])],
[Darwin/*], [PY_STDLIB_MOD_SET_NA([ossaudiodev], [spwd])],
[CYGWIN*/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])],
[QNX*/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])],
[FreeBSD*/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [spwd])],
[Emscripten/browser], [
py_stdlib_not_available="m4_normalize([
_ctypes
_curses
_curses_panel
_dbm
_gdbm
_multiprocessing
_posixshmem
_posixsubprocess
_scproxy
_tkinter
_xxsubinterpreters
fcntl
grp
nis
ossaudiodev
resource
readline
spwd
syslog
termios
])"
PY_STDLIB_MOD_SET_NA(
[_ctypes],
[_curses],
[_curses_panel],
[_dbm],
[_gdbm],
[_multiprocessing],
[_posixshmem],
[_posixsubprocess],
[_scproxy],
[_tkinter],
[_xxsubinterpreters],
[fcntl],
[grp],
[nis],
[ossaudiodev],
[pwd],
[resource],
[readline],
[spwd],
[syslog],
[termios],
)
],
dnl Some modules like _posixsubprocess do not work. We build them anyway
dnl so imports in tests do not fail.
[Emscripten/node], [
py_stdlib_not_available="m4_normalize([
_ctypes
_curses
_curses_panel
_dbm
_gdbm
_scproxy
_tkinter
_xxsubinterpreters
grp
nis
ossaudiodev
spwd
syslog
])"
PY_STDLIB_MOD_SET_NA(
[_ctypes],
[_curses],
[_curses_panel],
[_dbm],
[_gdbm],
[_scproxy],
[_tkinter],
[_xxsubinterpreters],
[grp],
[nis],
[ossaudiodev],
[pwd],
[spwd],
[syslog],
)
],
[py_stdlib_not_available="_scproxy"]
[PY_STDLIB_MOD_SET_NA([_scproxy])]
)
dnl AC_MSG_NOTICE([m4_set_list([_PY_STDLIB_MOD_SET_NA])])
dnl Default value for Modules/Setup.stdlib build type
AS_CASE([$host_cpu],
[wasm32|wasm64], [MODULE_BUILDTYPE=static],
@ -6450,10 +6460,10 @@ MODULE_BLOCK=
dnl Check for stdlib extension modules
dnl PY_STDLIB_MOD([NAME], [ENABLED-TEST], [SUPPORTED-TEST], [CFLAGS], [LDFLAGS])
dnl sets MODULE_$NAME based on $py_stdlib_not_available, ENABLED-TEST,
dnl sets MODULE_$NAME based on PY_STDLIB_MOD_SET_NA(), ENABLED-TEST,
dnl and SUPPORTED_TEST. ENABLED-TEST and SUPPORTED-TEST default to true if
dnl empty.
dnl n/a: $NAME in $py_stdlib_not_available (not available on platform)
dnl n/a: marked unavailable on platform by PY_STDLIB_MOD_SET_NA()
dnl yes: enabled and supported
dnl missing: enabled and not supported
dnl disabled: not enabled
@ -6462,12 +6472,12 @@ AC_DEFUN([PY_STDLIB_MOD], [
AC_MSG_CHECKING([for stdlib extension module $1])
m4_pushdef([modcond], [MODULE_]m4_toupper([$1]))dnl
m4_pushdef([modstate], [py_cv_module_$1])dnl
AS_CASE([$py_stdlib_not_available],
[*$1*], [modstate=n/a],
[AS_IF(m4_ifblank([$2], [true], [$2]),
[AS_IF([m4_ifblank([$3], [true], [$3])], [modstate=yes], [modstate=missing])],
[modstate=disabled])]
)
dnl Check if module has been disabled by PY_STDLIB_MOD_SET_NA()
AS_IF([test "$modstate" != "n/a"], [
AS_IF(m4_ifblank([$2], [true], [$2]),
[AS_IF([m4_ifblank([$3], [true], [$3])], [modstate=yes], [modstate=missing])],
[modstate=disabled])
])
_MODULE_BLOCK_ADD(modcond, [$modstate])
AS_VAR_IF([modstate], [yes], [
m4_ifblank([$4], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_CFLAGS], [$4])])
@ -6480,16 +6490,14 @@ AC_DEFUN([PY_STDLIB_MOD], [
])
dnl Define simple stdlib extension module
dnl Always enable unless the module is listed in py_stdlib_not_available
dnl Always enable unless the module is disabled by PY_STDLIB_MOD_SET_NA
dnl PY_STDLIB_MOD_SIMPLE([NAME], [CFLAGS], [LDFLAGS])
dnl cflags and ldflags are optional
AC_DEFUN([PY_STDLIB_MOD_SIMPLE], [
m4_pushdef([modcond], [MODULE_]m4_toupper([$1]))dnl
m4_pushdef([modstate], [py_cv_module_$1])dnl
AS_CASE([$py_stdlib_not_available],
[*$1*], [modstate=n/a],
[modstate=yes]
)
dnl Check if module has been disabled by PY_STDLIB_MOD_SET_NA()
AS_IF([test "$modstate" != "n/a"], [modstate=yes])
AM_CONDITIONAL(modcond, [test "$modstate" = yes])
_MODULE_BLOCK_ADD(modcond, [$modstate])
AS_VAR_IF([modstate], [yes], [
@ -6556,6 +6564,7 @@ dnl platform specific extensions
PY_STDLIB_MOD([grp], [], [test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes])
PY_STDLIB_MOD([ossaudiodev],
[], [test "$ac_cv_header_linux_soundcard_h" = yes -o "$ac_cv_header_sys_soundcard_h" = yes])
PY_STDLIB_MOD([pwd], [], [test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes])
PY_STDLIB_MOD([resource], [], [test "$ac_cv_header_sys_resource_h" = yes])
PY_STDLIB_MOD([_scproxy],
[test "$ac_sys_system" = "Darwin"], [],
@ -6645,7 +6654,7 @@ AC_SUBST([MODULE_BLOCK])
# generate output files
AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh)
AC_CONFIG_FILES([Modules/Setup.stdlib])
AC_CONFIG_FILES([Modules/Setup.bootstrap Modules/Setup.stdlib])
AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
AC_OUTPUT
@ -6658,7 +6667,7 @@ fi
AC_MSG_NOTICE([creating Makefile])
$SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \
-s Modules \
Modules/Setup.local $MODULES_SETUP_STDLIB $srcdir/Modules/Setup.bootstrap $srcdir/Modules/Setup
Modules/Setup.local $MODULES_SETUP_STDLIB Modules/Setup.bootstrap $srcdir/Modules/Setup
mv config.c Modules
if test -z "$PKG_CONFIG"; then

View file

@ -522,6 +522,9 @@
/* Define to 1 if you have the `getpwnam_r' function. */
#undef HAVE_GETPWNAM_R
/* Define to 1 if you have the `getpwuid' function. */
#undef HAVE_GETPWUID
/* Define to 1 if you have the `getpwuid_r' function. */
#undef HAVE_GETPWUID_R