[Python-checkins] gh-104773: PEP 594: Remove the spwd module (#104871)

vstinner webhook-mailer at python.org
Wed May 24 16:34:49 EDT 2023


https://github.com/python/cpython/commit/684e99d01df0c7c8f7c67567e2cece4673df9432
commit: 684e99d01df0c7c8f7c67567e2cece4673df9432
branch: main
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2023-05-24T20:34:41Z
summary:

gh-104773: PEP 594: Remove the spwd module (#104871)

Remove spwd from the configure script and Modules/Setup.

files:
A Misc/NEWS.d/next/Library/2023-05-24-17-47-25.gh-issue-104773.TzUSY2.rst
D Doc/library/spwd.rst
D Lib/test/test_spwd.py
D Modules/clinic/spwdmodule.c.h
D Modules/spwdmodule.c
M Doc/library/grp.rst
M Doc/library/pwd.rst
M Doc/library/superseded.rst
M Doc/whatsnew/2.5.rst
M Doc/whatsnew/3.11.rst
M Doc/whatsnew/3.12.rst
M Doc/whatsnew/3.13.rst
M Doc/whatsnew/3.6.rst
M Misc/NEWS.d/3.10.0a3.rst
M Modules/Setup
M Modules/Setup.stdlib.in
M Python/stdlib_module_names.h
M configure
M configure.ac

diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst
index 14af744e3ae8..8f88f82e1c21 100644
--- a/Doc/library/grp.rst
+++ b/Doc/library/grp.rst
@@ -63,7 +63,3 @@ It defines the following items:
 
    Module :mod:`pwd`
       An interface to the user database, similar to this.
-
-   Module :mod:`spwd`
-      An interface to the shadow password database, similar to this.
-
diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst
index 7cafc66fd7e9..25aa8b82754d 100644
--- a/Doc/library/pwd.rst
+++ b/Doc/library/pwd.rst
@@ -47,8 +47,7 @@ raised if the entry asked for cannot be found.
    *pw_passwd* field only contains an asterisk (``'*'``) or the  letter ``'x'``
    where the encrypted password is stored in a file :file:`/etc/shadow` which is
    not world readable.  Whether the *pw_passwd* field contains anything useful is
-   system-dependent.  If available, the :mod:`spwd` module should be used where
-   access to the encrypted password is required.
+   system-dependent.
 
 It defines the following items:
 
@@ -72,7 +71,3 @@ It defines the following items:
 
    Module :mod:`grp`
       An interface to the group database, similar to this.
-
-   Module :mod:`spwd`
-      An interface to the shadow password database, similar to this.
-
diff --git a/Doc/library/spwd.rst b/Doc/library/spwd.rst
deleted file mode 100644
index d1693ea67f0c..000000000000
--- a/Doc/library/spwd.rst
+++ /dev/null
@@ -1,82 +0,0 @@
-:mod:`spwd` --- The shadow password database
-============================================
-
-.. module:: spwd
-   :platform: Unix
-   :synopsis: The shadow password database (getspnam() and friends).
-   :deprecated:
-
-.. deprecated-removed:: 3.11 3.13
-   The :mod:`spwd` module is deprecated
-   (see :pep:`PEP 594 <594#spwd>` for details and alternatives).
-
---------------
-
-This module provides access to the Unix shadow password database. It is
-available on various Unix versions.
-
-.. include:: ../includes/wasm-notavail.rst
-
-You must have enough privileges to access the shadow password database (this
-usually means you have to be root).
-
-Shadow password database entries are reported as a tuple-like object, whose
-attributes correspond to the members of the ``spwd`` structure (Attribute field
-below, see ``<shadow.h>``):
-
-+-------+---------------+---------------------------------+
-| Index | Attribute     | Meaning                         |
-+=======+===============+=================================+
-| 0     | ``sp_namp``   | Login name                      |
-+-------+---------------+---------------------------------+
-| 1     | ``sp_pwdp``   | Encrypted password              |
-+-------+---------------+---------------------------------+
-| 2     | ``sp_lstchg`` | Date of last change             |
-+-------+---------------+---------------------------------+
-| 3     | ``sp_min``    | Minimal number of days between  |
-|       |               | changes                         |
-+-------+---------------+---------------------------------+
-| 4     | ``sp_max``    | Maximum number of days between  |
-|       |               | changes                         |
-+-------+---------------+---------------------------------+
-| 5     | ``sp_warn``   | Number of days before password  |
-|       |               | expires to warn user about it   |
-+-------+---------------+---------------------------------+
-| 6     | ``sp_inact``  | Number of days after password   |
-|       |               | expires until account is        |
-|       |               | disabled                        |
-+-------+---------------+---------------------------------+
-| 7     | ``sp_expire`` | Number of days since 1970-01-01 |
-|       |               | when account expires            |
-+-------+---------------+---------------------------------+
-| 8     | ``sp_flag``   | Reserved                        |
-+-------+---------------+---------------------------------+
-
-The sp_namp and sp_pwdp items are strings, all others are integers.
-:exc:`KeyError` is raised if the entry asked for cannot be found.
-
-The following functions are defined:
-
-
-.. function:: getspnam(name)
-
-   Return the shadow password database entry for the given user name.
-
-   .. versionchanged:: 3.6
-      Raises a :exc:`PermissionError` instead of :exc:`KeyError` if the user
-      doesn't have privileges.
-
-.. function:: getspall()
-
-   Return a list of all available shadow password database entries, in arbitrary
-   order.
-
-
-.. seealso::
-
-   Module :mod:`grp`
-      An interface to the group database, similar to this.
-
-   Module :mod:`pwd`
-      An interface to the normal password database, similar to this.
-
diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst
index 3c67ae491636..744073848cfe 100644
--- a/Doc/library/superseded.rst
+++ b/Doc/library/superseded.rst
@@ -19,6 +19,5 @@ backwards compatibility. They have been superseded by other modules.
    nis.rst
    nntplib.rst
    optparse.rst
-   spwd.rst
    uu.rst
    xdrlib.rst
diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst
index dcfaef6ed294..a679c7cfca92 100644
--- a/Doc/whatsnew/2.5.rst
+++ b/Doc/whatsnew/2.5.rst
@@ -1542,7 +1542,7 @@ complete list of changes, or look through the SVN logs for all the details.
   :meth:`getproto` accessor methods to retrieve the family, type, and protocol
   values for the socket.
 
-* New module: the :mod:`spwd` module provides functions for accessing the shadow
+* New module: the :mod:`!spwd` module provides functions for accessing the shadow
   password database on systems that support  shadow passwords.
 
 * The :mod:`struct` is now faster because it  compiles format strings into
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index fd4a75ce47b3..af600528aaac 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -1735,7 +1735,7 @@ Modules
   +---------------------+---------------------+---------------------+---------------------+---------------------+
   | :mod:`audioop`      | :mod:`crypt`        | :mod:`nis`          | :mod:`!sndhdr`      | :mod:`uu`           |
   +---------------------+---------------------+---------------------+---------------------+---------------------+
-  | :mod:`!cgi`         | :mod:`imghdr`       | :mod:`nntplib`      | :mod:`spwd`         | :mod:`xdrlib`       |
+  | :mod:`!cgi`         | :mod:`imghdr`       | :mod:`nntplib`      | :mod:`!spwd`        | :mod:`xdrlib`       |
   +---------------------+---------------------+---------------------+---------------------+---------------------+
   | :mod:`!cgitb`       | :mod:`!mailcap`     | :mod:`!ossaudiodev` | :mod:`!sunau`       |                     |
   +---------------------+---------------------+---------------------+---------------------+---------------------+
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 7bf0df17fb72..3de778cabf38 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -900,7 +900,7 @@ Modules (see :pep:`594`):
 * :mod:`!ossaudiodev`
 * :mod:`!pipes`
 * :mod:`!sndhdr`
-* :mod:`spwd`
+* :mod:`!spwd`
 * :mod:`!sunau`
 * :mod:`!telnetlib`
 * :mod:`uu`
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index 1102225e50b6..a94a69a852e9 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -168,6 +168,11 @@ Removed
   The :mod:`mimetypes` module provides an alternative.
   (Contributed by Victor Stinner in :gh:`104773`.)
 
+* :pep:`594`: Remove the :mod:`!spwd` module, deprecated in Python 3.11:
+  the `python-pam project <https://pypi.org/project/python-pam/>`_ can be used
+  instead.
+  (Contributed by Victor Stinner in :gh:`104773`.)
+
 
 Porting to Python 3.13
 ======================
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst
index 3d8f9322f927..944da78e9184 100644
--- a/Doc/whatsnew/3.6.rst
+++ b/Doc/whatsnew/3.6.rst
@@ -2211,7 +2211,7 @@ Changes in the Python API
   the exception will stop a single-threaded server. (Contributed by
   Martin Panter in :issue:`23430`.)
 
-* :func:`spwd.getspnam` now raises a :exc:`PermissionError` instead of
+* :func:`!spwd.getspnam` now raises a :exc:`PermissionError` instead of
   :exc:`KeyError` if the user doesn't have privileges.
 
 * The :meth:`socket.socket.close` method now raises an exception if
diff --git a/Lib/test/test_spwd.py b/Lib/test/test_spwd.py
deleted file mode 100644
index 50766c25482a..000000000000
--- a/Lib/test/test_spwd.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import os
-import unittest
-from test.support import import_helper
-import warnings
-
-
-with warnings.catch_warnings():
-    warnings.simplefilter("ignore", DeprecationWarning)
-    spwd = import_helper.import_module('spwd')
-
-
- at unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0,
-                     'root privileges required')
-class TestSpwdRoot(unittest.TestCase):
-
-    def test_getspall(self):
-        entries = spwd.getspall()
-        self.assertIsInstance(entries, list)
-        for entry in entries:
-            self.assertIsInstance(entry, spwd.struct_spwd)
-
-    def test_getspnam(self):
-        entries = spwd.getspall()
-        if not entries:
-            self.skipTest('empty shadow password database')
-        random_name = entries[0].sp_namp
-        entry = spwd.getspnam(random_name)
-        self.assertIsInstance(entry, spwd.struct_spwd)
-        self.assertEqual(entry.sp_namp, random_name)
-        self.assertEqual(entry.sp_namp, entry[0])
-        self.assertEqual(entry.sp_namp, entry.sp_nam)
-        self.assertIsInstance(entry.sp_pwdp, str)
-        self.assertEqual(entry.sp_pwdp, entry[1])
-        self.assertEqual(entry.sp_pwdp, entry.sp_pwd)
-        self.assertIsInstance(entry.sp_lstchg, int)
-        self.assertEqual(entry.sp_lstchg, entry[2])
-        self.assertIsInstance(entry.sp_min, int)
-        self.assertEqual(entry.sp_min, entry[3])
-        self.assertIsInstance(entry.sp_max, int)
-        self.assertEqual(entry.sp_max, entry[4])
-        self.assertIsInstance(entry.sp_warn, int)
-        self.assertEqual(entry.sp_warn, entry[5])
-        self.assertIsInstance(entry.sp_inact, int)
-        self.assertEqual(entry.sp_inact, entry[6])
-        self.assertIsInstance(entry.sp_expire, int)
-        self.assertEqual(entry.sp_expire, entry[7])
-        self.assertIsInstance(entry.sp_flag, int)
-        self.assertEqual(entry.sp_flag, entry[8])
-        with self.assertRaises(KeyError) as cx:
-            spwd.getspnam('invalid user name')
-        self.assertEqual(str(cx.exception), "'getspnam(): name not found'")
-        self.assertRaises(TypeError, spwd.getspnam)
-        self.assertRaises(TypeError, spwd.getspnam, 0)
-        self.assertRaises(TypeError, spwd.getspnam, random_name, 0)
-        try:
-            bytes_name = os.fsencode(random_name)
-        except UnicodeEncodeError:
-            pass
-        else:
-            self.assertRaises(TypeError, spwd.getspnam, bytes_name)
-
-
- at unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() != 0,
-                     'non-root user required')
-class TestSpwdNonRoot(unittest.TestCase):
-
-    def test_getspnam_exception(self):
-        name = 'bin'
-        try:
-            with self.assertRaises(PermissionError) as cm:
-                spwd.getspnam(name)
-        except KeyError as exc:
-            self.skipTest("spwd entry %r doesn't exist: %s" % (name, exc))
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/Misc/NEWS.d/3.10.0a3.rst b/Misc/NEWS.d/3.10.0a3.rst
index 699a0dd9e8d7..f24b6d43e578 100644
--- a/Misc/NEWS.d/3.10.0a3.rst
+++ b/Misc/NEWS.d/3.10.0a3.rst
@@ -1296,7 +1296,7 @@ Port _struct extension module to multiphase initialization (:pep:`489`)
 .. nonce: 6F9o6L
 .. section: C API
 
-Port :mod:`spwd` extension module to multiphase initialization (:pep:`489`)
+Port :mod:`!spwd` extension module to multiphase initialization (:pep:`489`)
 
 ..
 
diff --git a/Misc/NEWS.d/next/Library/2023-05-24-17-47-25.gh-issue-104773.TzUSY2.rst b/Misc/NEWS.d/next/Library/2023-05-24-17-47-25.gh-issue-104773.TzUSY2.rst
new file mode 100644
index 000000000000..221948957056
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-24-17-47-25.gh-issue-104773.TzUSY2.rst
@@ -0,0 +1,3 @@
+:pep:`594`: Remove the :mod:`!spwd` module, deprecated in Python 3.11: the
+`python-pam project <https://pypi.org/project/python-pam/>`_ can be used
+instead. Patch by Victor Stinner.
diff --git a/Modules/Setup b/Modules/Setup
index e7c64f784739..79a5124e31db 100644
--- a/Modules/Setup
+++ b/Modules/Setup
@@ -185,7 +185,6 @@ PYTHONPATH=$(COREPYTHONPATH)
 #fcntl fcntlmodule.c
 #grp grpmodule.c
 #resource resource.c
-#spwd spwdmodule.c
 #syslog syslogmodule.c
 #termios termios.c
 
diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index 3e3d8c6a2130..dbad7ba8b20b 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -119,8 +119,6 @@
 @MODULE_RESOURCE_TRUE at resource resource.c
 @MODULE_SELECT_TRUE at select selectmodule.c
 @MODULE__SOCKET_TRUE at _socket socketmodule.c
-# AIX has shadow passwords, but does not provide getspent API
- at MODULE_SPWD_TRUE@spwd spwdmodule.c
 @MODULE_SYSLOG_TRUE at syslog syslogmodule.c
 @MODULE_TERMIOS_TRUE at termios termios.c
 
diff --git a/Modules/clinic/spwdmodule.c.h b/Modules/clinic/spwdmodule.c.h
deleted file mode 100644
index f47aa9a77f3f..000000000000
--- a/Modules/clinic/spwdmodule.c.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*[clinic input]
-preserve
-[clinic start generated code]*/
-
-#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
-#  include "pycore_gc.h"            // PyGC_Head
-#  include "pycore_runtime.h"       // _Py_ID()
-#endif
-
-
-#if defined(HAVE_GETSPNAM)
-
-PyDoc_STRVAR(spwd_getspnam__doc__,
-"getspnam($module, arg, /)\n"
-"--\n"
-"\n"
-"Return the shadow password database entry for the given user name.\n"
-"\n"
-"See `help(spwd)` for more on shadow password database entries.");
-
-#define SPWD_GETSPNAM_METHODDEF    \
-    {"getspnam", (PyCFunction)spwd_getspnam, METH_O, spwd_getspnam__doc__},
-
-static PyObject *
-spwd_getspnam_impl(PyObject *module, PyObject *arg);
-
-static PyObject *
-spwd_getspnam(PyObject *module, PyObject *arg_)
-{
-    PyObject *return_value = NULL;
-    PyObject *arg;
-
-    if (!PyUnicode_Check(arg_)) {
-        _PyArg_BadArgument("getspnam", "argument", "str", arg_);
-        goto exit;
-    }
-    if (PyUnicode_READY(arg_) == -1) {
-        goto exit;
-    }
-    arg = arg_;
-    return_value = spwd_getspnam_impl(module, arg);
-
-exit:
-    return return_value;
-}
-
-#endif /* defined(HAVE_GETSPNAM) */
-
-#if defined(HAVE_GETSPENT)
-
-PyDoc_STRVAR(spwd_getspall__doc__,
-"getspall($module, /)\n"
-"--\n"
-"\n"
-"Return a list of all available shadow password database entries, in arbitrary order.\n"
-"\n"
-"See `help(spwd)` for more on shadow password database entries.");
-
-#define SPWD_GETSPALL_METHODDEF    \
-    {"getspall", (PyCFunction)spwd_getspall, METH_NOARGS, spwd_getspall__doc__},
-
-static PyObject *
-spwd_getspall_impl(PyObject *module);
-
-static PyObject *
-spwd_getspall(PyObject *module, PyObject *Py_UNUSED(ignored))
-{
-    return spwd_getspall_impl(module);
-}
-
-#endif /* defined(HAVE_GETSPENT) */
-
-#ifndef SPWD_GETSPNAM_METHODDEF
-    #define SPWD_GETSPNAM_METHODDEF
-#endif /* !defined(SPWD_GETSPNAM_METHODDEF) */
-
-#ifndef SPWD_GETSPALL_METHODDEF
-    #define SPWD_GETSPALL_METHODDEF
-#endif /* !defined(SPWD_GETSPALL_METHODDEF) */
-/*[clinic end generated code: output=dd61827a7b708e11 input=a9049054013a1b77]*/
diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c
deleted file mode 100644
index 13f1115feefa..000000000000
--- a/Modules/spwdmodule.c
+++ /dev/null
@@ -1,268 +0,0 @@
-
-/* UNIX shadow password file access module */
-/* A lot of code has been taken from pwdmodule.c */
-/* For info also see http://www.unixpapa.com/incnote/passwd.html */
-
-#include "Python.h"
-
-#include <sys/types.h>
-#ifdef HAVE_SHADOW_H
-#include <shadow.h>
-#endif
-
-#include "clinic/spwdmodule.c.h"
-
-/*[clinic input]
-module spwd
-[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c0b841b90a6a07ce]*/
-
-PyDoc_STRVAR(spwd__doc__,
-"This module provides access to the Unix shadow password database.\n\
-It is available on various Unix versions.\n\
-\n\
-Shadow password database entries are reported as 9-tuples of type struct_spwd,\n\
-containing the following items from the password database (see `<shadow.h>'):\n\
-sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max, sp_warn, sp_inact, sp_expire, sp_flag.\n\
-The sp_namp and sp_pwdp are strings, the rest are integers.\n\
-An exception is raised if the entry asked for cannot be found.\n\
-You have to be root to be able to use this module.");
-
-
-#if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT)
-
-static PyStructSequence_Field struct_spwd_type_fields[] = {
-    {"sp_namp", "login name"},
-    {"sp_pwdp", "encrypted password"},
-    {"sp_lstchg", "date of last change"},
-    {"sp_min", "min #days between changes"},
-    {"sp_max", "max #days between changes"},
-    {"sp_warn", "#days before pw expires to warn user about it"},
-    {"sp_inact", "#days after pw expires until account is disabled"},
-    {"sp_expire", "#days since 1970-01-01 when account expires"},
-    {"sp_flag", "reserved"},
-    {"sp_nam", "login name; deprecated"}, /* Backward compatibility */
-    {"sp_pwd", "encrypted password; deprecated"}, /* Backward compatibility */
-    {0}
-};
-
-PyDoc_STRVAR(struct_spwd__doc__,
-"spwd.struct_spwd: Results from getsp*() routines.\n\n\
-This object may be accessed either as a 9-tuple of\n\
-  (sp_namp,sp_pwdp,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\
-or via the object attributes as named in the above tuple.");
-
-static PyStructSequence_Desc struct_spwd_type_desc = {
-    "spwd.struct_spwd",
-    struct_spwd__doc__,
-    struct_spwd_type_fields,
-    9,
-};
-
-typedef struct {
-    PyTypeObject *StructSpwdType;
-} spwdmodulestate;
-
-static inline spwdmodulestate*
-get_spwd_state(PyObject *module)
-{
-    void *state = PyModule_GetState(module);
-    assert(state != NULL);
-    return (spwdmodulestate *)state;
-}
-
-static struct PyModuleDef spwdmodule;
-
-static void
-sets(PyObject *v, int i, const char* val)
-{
-  if (val) {
-      PyObject *o = PyUnicode_DecodeFSDefault(val);
-      PyStructSequence_SET_ITEM(v, i, o);
-  } else {
-      PyStructSequence_SET_ITEM(v, i, Py_None);
-      Py_INCREF(Py_None);
-  }
-}
-
-static PyObject *mkspent(PyObject *module, struct spwd *p)
-{
-    int setIndex = 0;
-    PyObject *v = PyStructSequence_New(get_spwd_state(module)->StructSpwdType);
-    if (v == NULL)
-        return NULL;
-
-#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val))
-#define SETS(i,val) sets(v, i, val)
-
-    SETS(setIndex++, p->sp_namp);
-    SETS(setIndex++, p->sp_pwdp);
-    SETI(setIndex++, p->sp_lstchg);
-    SETI(setIndex++, p->sp_min);
-    SETI(setIndex++, p->sp_max);
-    SETI(setIndex++, p->sp_warn);
-    SETI(setIndex++, p->sp_inact);
-    SETI(setIndex++, p->sp_expire);
-    SETI(setIndex++, p->sp_flag);
-    SETS(setIndex++, p->sp_namp); /* Backward compatibility for sp_nam */
-    SETS(setIndex++, p->sp_pwdp); /* Backward compatibility for sp_pwd */
-
-#undef SETS
-#undef SETI
-
-    if (PyErr_Occurred()) {
-        Py_DECREF(v);
-        return NULL;
-    }
-
-    return v;
-}
-
-#endif  /* HAVE_GETSPNAM || HAVE_GETSPENT */
-
-
-#ifdef HAVE_GETSPNAM
-
-/*[clinic input]
-spwd.getspnam
-
-    arg: unicode
-    /
-
-Return the shadow password database entry for the given user name.
-
-See `help(spwd)` for more on shadow password database entries.
-[clinic start generated code]*/
-
-static PyObject *
-spwd_getspnam_impl(PyObject *module, PyObject *arg)
-/*[clinic end generated code: output=701250cf57dc6ebe input=dd89429e6167a00f]*/
-{
-    char *name;
-    struct spwd *p;
-    PyObject *bytes, *retval = NULL;
-
-    if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL)
-        return NULL;
-    /* check for embedded null bytes */
-    if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
-        goto out;
-    if ((p = getspnam(name)) == NULL) {
-        if (errno != 0)
-            PyErr_SetFromErrno(PyExc_OSError);
-        else
-            PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
-        goto out;
-    }
-    retval = mkspent(module, p);
-out:
-    Py_DECREF(bytes);
-    return retval;
-}
-
-#endif /* HAVE_GETSPNAM */
-
-#ifdef HAVE_GETSPENT
-
-/*[clinic input]
-spwd.getspall
-
-Return a list of all available shadow password database entries, in arbitrary order.
-
-See `help(spwd)` for more on shadow password database entries.
-[clinic start generated code]*/
-
-static PyObject *
-spwd_getspall_impl(PyObject *module)
-/*[clinic end generated code: output=4fda298d6bf6d057 input=b2c84b7857d622bd]*/
-{
-    PyObject *d;
-    struct spwd *p;
-    if ((d = PyList_New(0)) == NULL)
-        return NULL;
-    setspent();
-    while ((p = getspent()) != NULL) {
-        PyObject *v = mkspent(module, p);
-        if (v == NULL || PyList_Append(d, v) != 0) {
-            Py_XDECREF(v);
-            Py_DECREF(d);
-            endspent();
-            return NULL;
-        }
-        Py_DECREF(v);
-    }
-    endspent();
-    return d;
-}
-
-#endif /* HAVE_GETSPENT */
-
-static PyMethodDef spwd_methods[] = {
-#ifdef HAVE_GETSPNAM
-    SPWD_GETSPNAM_METHODDEF
-#endif
-#ifdef HAVE_GETSPENT
-    SPWD_GETSPALL_METHODDEF
-#endif
-    {NULL,              NULL}           /* sentinel */
-};
-
-static int
-spwdmodule_exec(PyObject *module)
-{
-    spwdmodulestate *state = get_spwd_state(module);
-
-    state->StructSpwdType = PyStructSequence_NewType(&struct_spwd_type_desc);
-    if (state->StructSpwdType == NULL) {
-        return -1;
-    }
-    if (PyModule_AddType(module, state->StructSpwdType) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static PyModuleDef_Slot spwdmodule_slots[] = {
-    {Py_mod_exec, spwdmodule_exec},
-    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
-    {0, NULL}
-};
-
-static int spwdmodule_traverse(PyObject *m, visitproc visit, void *arg) {
-    Py_VISIT(get_spwd_state(m)->StructSpwdType);
-    return 0;
-}
-
-static int spwdmodule_clear(PyObject *m) {
-    Py_CLEAR(get_spwd_state(m)->StructSpwdType);
-    return 0;
-}
-
-static void spwdmodule_free(void *m) {
-    spwdmodule_clear((PyObject *)m);
-}
-
-static struct PyModuleDef spwdmodule = {
-    PyModuleDef_HEAD_INIT,
-    .m_name = "spwd",
-    .m_doc = spwd__doc__,
-    .m_size = sizeof(spwdmodulestate),
-    .m_methods = spwd_methods,
-    .m_slots = spwdmodule_slots,
-    .m_traverse = spwdmodule_traverse,
-    .m_clear = spwdmodule_clear,
-    .m_free = spwdmodule_free,
-};
-
-PyMODINIT_FUNC
-PyInit_spwd(void)
-{
-    if (PyErr_WarnEx(PyExc_DeprecationWarning,
-                     "'spwd' is deprecated and slated for removal in "
-                     "Python 3.13",
-                     7)) {
-        return NULL;
-    }
-
-    return PyModuleDef_Init(&spwdmodule);
-}
diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h
index 7aaa4f4ccdb3..d91fea3e022e 100644
--- a/Python/stdlib_module_names.h
+++ b/Python/stdlib_module_names.h
@@ -235,7 +235,6 @@ static const char* _Py_stdlib_module_names[] = {
 "smtplib",
 "socket",
 "socketserver",
-"spwd",
 "sqlite3",
 "sre_compile",
 "sre_constants",
diff --git a/configure b/configure
index 9ff7f18336bd..053e001925ec 100755
--- a/configure
+++ b/configure
@@ -716,8 +716,6 @@ MODULE_TERMIOS_FALSE
 MODULE_TERMIOS_TRUE
 MODULE_SYSLOG_FALSE
 MODULE_SYSLOG_TRUE
-MODULE_SPWD_FALSE
-MODULE_SPWD_TRUE
 MODULE__SCPROXY_FALSE
 MODULE__SCPROXY_TRUE
 MODULE_RESOURCE_FALSE
@@ -25651,7 +25649,6 @@ case $ac_sys_system in #(
 
 
     py_cv_module__scproxy=n/a
-    py_cv_module_spwd=n/a
  ;; #(
   VxWorks*) :
 
@@ -25660,11 +25657,6 @@ case $ac_sys_system in #(
     py_cv_module__crypt=n/a
     py_cv_module_termios=n/a
     py_cv_module_grp=n/a
- ;; #(
-  Darwin) :
-
-
-    py_cv_module_spwd=n/a
  ;; #(
   CYGWIN*) :
 
@@ -25682,7 +25674,6 @@ case $ac_sys_system in #(
 
 
     py_cv_module__scproxy=n/a
-    py_cv_module_spwd=n/a
  ;; #(
   Emscripten|WASI) :
 
@@ -25703,7 +25694,6 @@ case $ac_sys_system in #(
     py_cv_module_nis=n/a
     py_cv_module_pwd=n/a
     py_cv_module_resource=n/a
-    py_cv_module_spwd=n/a
     py_cv_module_syslog=n/a
     py_cv_module_=n/a
 
@@ -26594,40 +26584,6 @@ fi
 $as_echo "$py_cv_module__scproxy" >&6; }
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module spwd" >&5
-$as_echo_n "checking for stdlib extension module spwd... " >&6; }
-        if test "$py_cv_module_spwd" != "n/a"; then :
-
-    if true; then :
-  if test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes; then :
-  py_cv_module_spwd=yes
-else
-  py_cv_module_spwd=missing
-fi
-else
-  py_cv_module_spwd=disabled
-fi
-
-fi
-  as_fn_append MODULE_BLOCK "MODULE_SPWD_STATE=$py_cv_module_spwd$as_nl"
-  if test "x$py_cv_module_spwd" = xyes; then :
-
-
-
-
-fi
-   if test "$py_cv_module_spwd" = yes; then
-  MODULE_SPWD_TRUE=
-  MODULE_SPWD_FALSE='#'
-else
-  MODULE_SPWD_TRUE='#'
-  MODULE_SPWD_FALSE=
-fi
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_spwd" >&5
-$as_echo "$py_cv_module_spwd" >&6; }
-
-
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module syslog" >&5
 $as_echo_n "checking for stdlib extension module syslog... " >&6; }
         if test "$py_cv_module_syslog" != "n/a"; then :
@@ -28335,10 +28291,6 @@ if test -z "${MODULE__SCPROXY_TRUE}" && test -z "${MODULE__SCPROXY_FALSE}"; then
   as_fn_error $? "conditional \"MODULE__SCPROXY\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${MODULE_SPWD_TRUE}" && test -z "${MODULE_SPWD_FALSE}"; then
-  as_fn_error $? "conditional \"MODULE_SPWD\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${MODULE_SYSLOG_TRUE}" && test -z "${MODULE_SYSLOG_FALSE}"; then
   as_fn_error $? "conditional \"MODULE_SYSLOG\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/configure.ac b/configure.ac
index e3c7662738d7..325df16a5b84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7082,15 +7082,13 @@ AC_DEFUN([PY_STDLIB_MOD_SET_NA], [
 
 # 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],
-  [AIX], [PY_STDLIB_MOD_SET_NA([_scproxy], [spwd])],
+  [AIX], [PY_STDLIB_MOD_SET_NA([_scproxy])],
   [VxWorks*], [PY_STDLIB_MOD_SET_NA([_scproxy], [_crypt], [termios], [grp])],
-  [Darwin], [PY_STDLIB_MOD_SET_NA([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])],
+  [FreeBSD*], [PY_STDLIB_MOD_SET_NA([_scproxy])],
   [Emscripten|WASI], [
     dnl subprocess and multiprocessing are not supported (no fork syscall).
     dnl curses and tkinter user interface are not available.
@@ -7113,7 +7111,6 @@ AS_CASE([$ac_sys_system],
       [nis],
       [pwd],
       [resource],
-      [spwd],
       [syslog],
     )
     AS_CASE([$ac_sys_system/$ac_sys_emscripten_target],
@@ -7264,7 +7261,6 @@ PY_STDLIB_MOD([resource], [], [test "$ac_cv_header_sys_resource_h" = yes])
 PY_STDLIB_MOD([_scproxy],
   [test "$ac_sys_system" = "Darwin"], [],
   [], [-framework SystemConfiguration -framework CoreFoundation])
-PY_STDLIB_MOD([spwd], [], [test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes])
 PY_STDLIB_MOD([syslog], [], [test "$ac_cv_header_syslog_h" = yes])
 PY_STDLIB_MOD([termios], [], [test "$ac_cv_header_termios_h" = yes])
 



More information about the Python-checkins mailing list