From 684e99d01df0c7c8f7c67567e2cece4673df9432 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 24 May 2023 22:34:41 +0200 Subject: [PATCH] gh-104773: PEP 594: Remove the spwd module (#104871) Remove spwd from the configure script and Modules/Setup. --- Doc/library/grp.rst | 4 - Doc/library/pwd.rst | 7 +- Doc/library/spwd.rst | 82 ------ Doc/library/superseded.rst | 1 - Doc/whatsnew/2.5.rst | 2 +- Doc/whatsnew/3.11.rst | 2 +- Doc/whatsnew/3.12.rst | 2 +- Doc/whatsnew/3.13.rst | 5 + Doc/whatsnew/3.6.rst | 2 +- Lib/test/test_spwd.py | 77 ----- Misc/NEWS.d/3.10.0a3.rst | 2 +- ...-05-24-17-47-25.gh-issue-104773.TzUSY2.rst | 3 + Modules/Setup | 1 - Modules/Setup.stdlib.in | 2 - Modules/clinic/spwdmodule.c.h | 80 ------ Modules/spwdmodule.c | 268 ------------------ Python/stdlib_module_names.h | 1 - configure | 48 ---- configure.ac | 8 +- 19 files changed, 16 insertions(+), 581 deletions(-) delete mode 100644 Doc/library/spwd.rst delete mode 100644 Lib/test/test_spwd.py create mode 100644 Misc/NEWS.d/next/Library/2023-05-24-17-47-25.gh-issue-104773.TzUSY2.rst delete mode 100644 Modules/clinic/spwdmodule.c.h delete mode 100644 Modules/spwdmodule.c diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index 14af744e3ae..8f88f82e1c2 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 7cafc66fd7e..25aa8b82754 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 d1693ea67f0..00000000000 --- 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 ````): - -+-------+---------------+---------------------------------+ -| 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 3c67ae49163..744073848cf 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 dcfaef6ed29..a679c7cfca9 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 fd4a75ce47b..af600528aaa 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 7bf0df17fb7..3de778cabf3 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 1102225e50b..a94a69a852e 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 `_ 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 3d8f9322f92..944da78e918 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 50766c25482..00000000000 --- 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') - - -@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) - - -@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 699a0dd9e8d..f24b6d43e57 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 00000000000..22194895705 --- /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 `_ can be used +instead. Patch by Victor Stinner. diff --git a/Modules/Setup b/Modules/Setup index e7c64f78473..79a5124e31d 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 3e3d8c6a213..dbad7ba8b20 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -119,8 +119,6 @@ @MODULE_RESOURCE_TRUE@resource resource.c @MODULE_SELECT_TRUE@select selectmodule.c @MODULE__SOCKET_TRUE@_socket socketmodule.c -# AIX has shadow passwords, but does not provide getspent API -@MODULE_SPWD_TRUE@spwd spwdmodule.c @MODULE_SYSLOG_TRUE@syslog syslogmodule.c @MODULE_TERMIOS_TRUE@termios termios.c diff --git a/Modules/clinic/spwdmodule.c.h b/Modules/clinic/spwdmodule.c.h deleted file mode 100644 index f47aa9a77f3..00000000000 --- 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 13f1115feef..00000000000 --- 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 -#ifdef HAVE_SHADOW_H -#include -#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 `'):\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 7aaa4f4ccdb..d91fea3e022 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 9ff7f18336b..053e001925e 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 e3c7662738d..325df16a5b8 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])