]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-139482: Add `posix._clearenv()` function (#139965)
authorVictor Stinner <vstinner@python.org>
Sat, 11 Oct 2025 20:58:43 +0000 (22:58 +0200)
committerGitHub <noreply@github.com>
Sat, 11 Oct 2025 20:58:43 +0000 (22:58 +0200)
Lib/os.py
Lib/test/test_os/test_os.py
Misc/NEWS.d/next/Library/2025-10-11-20-03-13.gh-issue-139482.du2Stg.rst [new file with mode: 0644]
Modules/clinic/posixmodule.c.h
Modules/posixmodule.c
configure
configure.ac
pyconfig.h.in

index 710d6f8cfcdf74fe326723d8b8658a8202198070..328d13c303b580cdb332f8a827a939a8be1621b7 100644 (file)
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -58,6 +58,11 @@ if 'posix' in _names:
         __all__.append('_exit')
     except ImportError:
         pass
+    try:
+        from posix import _clearenv
+        __all__.append('_clearenv')
+    except ImportError:
+        pass
     import posixpath as path
 
     try:
@@ -768,6 +773,12 @@ class _Environ(MutableMapping):
         new.update(self)
         return new
 
+    if _exists("_clearenv"):
+        def clear(self):
+            _clearenv()
+            self._data.clear()
+
+
 def _create_environ_mapping():
     if name == 'nt':
         # Where Env Var Names Must Be UPPERCASE
index e074858fe2ad998a034f781c9f4a4e2f549dca0c..86880a6d2813151b3b981a2f8ae200502beeb40e 100644 (file)
@@ -1494,6 +1494,14 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol):
             self.assertNotIn(b'test_env', os.environb)
             self.assertNotIn('test_env', os.environ)
 
+    def test_clearenv(self):
+        os.environ['REMOVEME'] = '1'
+        os.environ.clear()
+        self.assertEqual(os.environ, {})
+
+        self.assertRaises(TypeError, os.environ.clear, None)
+
+
 class WalkTests(unittest.TestCase):
     """Tests for os.walk()."""
     is_fwalk = False
diff --git a/Misc/NEWS.d/next/Library/2025-10-11-20-03-13.gh-issue-139482.du2Stg.rst b/Misc/NEWS.d/next/Library/2025-10-11-20-03-13.gh-issue-139482.du2Stg.rst
new file mode 100644 (file)
index 0000000..4edd3d2
--- /dev/null
@@ -0,0 +1,3 @@
+Optimize :data:`os.environ.clear() <os.environ>` by calling
+:manpage:`clearenv(3)` when this function is available.
+Patch by Victor Stinner.
index 3d9863ad179d3c9619a2ba3cea31e8c1e9791912..71f87ac8ec7cf467cd4d2d86d60cb9057dee45d3 100644 (file)
@@ -9539,6 +9539,27 @@ exit:
 
 #endif /* !defined(MS_WINDOWS) */
 
+#if defined(HAVE_CLEARENV)
+
+PyDoc_STRVAR(os__clearenv__doc__,
+"_clearenv($module, /)\n"
+"--\n"
+"\n");
+
+#define OS__CLEARENV_METHODDEF    \
+    {"_clearenv", (PyCFunction)os__clearenv, METH_NOARGS, os__clearenv__doc__},
+
+static PyObject *
+os__clearenv_impl(PyObject *module);
+
+static PyObject *
+os__clearenv(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return os__clearenv_impl(module);
+}
+
+#endif /* defined(HAVE_CLEARENV) */
+
 PyDoc_STRVAR(os_strerror__doc__,
 "strerror($module, code, /)\n"
 "--\n"
@@ -13292,6 +13313,10 @@ exit:
     #define OS_UNSETENV_METHODDEF
 #endif /* !defined(OS_UNSETENV_METHODDEF) */
 
+#ifndef OS__CLEARENV_METHODDEF
+    #define OS__CLEARENV_METHODDEF
+#endif /* !defined(OS__CLEARENV_METHODDEF) */
+
 #ifndef OS_WCOREDUMP_METHODDEF
     #define OS_WCOREDUMP_METHODDEF
 #endif /* !defined(OS_WCOREDUMP_METHODDEF) */
@@ -13447,4 +13472,4 @@ exit:
 #ifndef OS__EMSCRIPTEN_LOG_METHODDEF
     #define OS__EMSCRIPTEN_LOG_METHODDEF
 #endif /* !defined(OS__EMSCRIPTEN_LOG_METHODDEF) */
-/*[clinic end generated code: output=47ace1528820858b input=a9049054013a1b77]*/
+/*[clinic end generated code: output=67f0df7cd5a7de20 input=a9049054013a1b77]*/
index 8278902cbeb349bff292f2adf02af1be9e49c1f3..38ddc3ec4ffc3dcad1240f7010339142c531dfdc 100644 (file)
@@ -13201,6 +13201,25 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
 #endif /* !MS_WINDOWS */
 
 
+#ifdef HAVE_CLEARENV
+/*[clinic input]
+os._clearenv
+[clinic start generated code]*/
+
+static PyObject *
+os__clearenv_impl(PyObject *module)
+/*[clinic end generated code: output=2d6705d62c014b51 input=47d2fa7f323c43ca]*/
+{
+    errno = 0;
+    int err = clearenv();
+    if (err) {
+        return posix_error();
+    }
+    Py_RETURN_NONE;
+}
+#endif
+
+
 /*[clinic input]
 os.strerror
 
@@ -17167,6 +17186,7 @@ static PyMethodDef posix_methods[] = {
     OS_POSIX_FADVISE_METHODDEF
     OS_PUTENV_METHODDEF
     OS_UNSETENV_METHODDEF
+    OS__CLEARENV_METHODDEF
     OS_STRERROR_METHODDEF
     OS_FCHDIR_METHODDEF
     OS_FSYNC_METHODDEF
index d80340e3015bee59640c0f09747682179d68f0aa..211f84399064a0e7e24f9829b8ebcf94f852c2f2 100755 (executable)
--- a/configure
+++ b/configure
@@ -19225,6 +19225,12 @@ if test "x$ac_cv_func_chown" = xyes
 then :
   printf "%s\n" "#define HAVE_CHOWN 1" >>confdefs.h
 
+fi
+ac_fn_c_check_func "$LINENO" "clearenv" "ac_cv_func_clearenv"
+if test "x$ac_cv_func_clearenv" = xyes
+then :
+  printf "%s\n" "#define HAVE_CLEARENV 1" >>confdefs.h
+
 fi
 ac_fn_c_check_func "$LINENO" "clock" "ac_cv_func_clock"
 if test "x$ac_cv_func_clock" = xyes
index 1e0c0f71b7c28135f2de37eb7d988039245b6795..35bf153a8987b216e8f215cf832c9631add044c1 100644 (file)
@@ -5226,7 +5226,8 @@ fi
 
 # checks for library functions
 AC_CHECK_FUNCS([ \
-  accept4 alarm bind_textdomain_codeset chmod chown clock closefrom close_range confstr \
+  accept4 alarm bind_textdomain_codeset chmod chown clearenv \
+  clock closefrom close_range confstr \
   copy_file_range ctermid dladdr dup dup3 execv explicit_bzero explicit_memset \
   faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
   fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
@@ -8173,7 +8174,7 @@ PY_STDLIB_MOD([xxlimited_35], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_d
 
 # Determine JIT stencils header files based on target platform
 JIT_STENCILS_H=""
-AS_VAR_IF([enable_experimental_jit], [no], 
+AS_VAR_IF([enable_experimental_jit], [no],
   [],
   [case "$host" in
     aarch64-apple-darwin*)
index 60bff4a9f2635613399b99f1532a675f52986dd0..72870411bc086ab88454bfadb69765d9e174aadf 100644 (file)
 /* Define if you have the 'chroot' function. */
 #undef HAVE_CHROOT
 
+/* Define to 1 if you have the 'clearenv' function. */
+#undef HAVE_CLEARENV
+
 /* Define to 1 if you have the 'clock' function. */
 #undef HAVE_CLOCK