Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

`test_is_python_process_non_python_subprocess` always times out when `sleep` is a multicall binary (Alpine/BusyBox, RHEL UBI9)

Abierto Apto para principiantes
#160,881 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
76/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
linux, python

Línea de trabajo

Lee Lib/test/test_profiling/test_sampling_profiler/test_children.py, especialmente _wait_for_process_exec() y test_is_python_process_non_python_subprocess. El issue incluye una comprobación propuesta que detecta cuándo cambia el ejecutable del proceso hijo, independientemente de su nombre. Actualiza el helper y el lugar donde se llama y, después, ejecuta el test indicado en Linux; debería pasar tanto con binarios sleep multicall como con binarios normales.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

tests topic-profiling type-bug
Bug report
Bug description:

The fix for gh-159534 (GH-160028, backported to 3.15 in GH-160080) makes test_is_python_process_non_python_subprocess fail every time on systems where sleep is provided by a multicall binary. That includes the Alpine buildbots, where the original gh-159534 failure was found:

FAIL: test_is_python_process_non_python_subprocess (test.test_profiling.test_sampling_profiler.test_children.TestIsPythonProcess.test_is_python_process_non_python_subprocess)
Test that a non-Python subprocess is not detected as Python.
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".../Lib/test/test_profiling/test_sampling_profiler/test_children.py", line 628, in test_is_python_process_non_python_subprocess
    _wait_for_process_exec(proc, "sleep", SHORT_TIMEOUT)
  File ".../Lib/test/test_profiling/test_sampling_profiler/test_children.py", line 91, in _wait_for_process_exec
    for _ in sleeping_retry(timeout, max_delay=0.1):
  File ".../Lib/test/support/__init__.py", line 2779, in sleeping_retry
    for _ in busy_retry(timeout, err_msg, error=error):
  File ".../Lib/test/support/__init__.py", line 2749, in busy_retry
    raise AssertionError(msg)
AssertionError: timeout (45.1 seconds)
Buildbots

AMD64 Alpine Linux NoGIL 3.x:

  • build 3444 (before GH-160028): the original intermittent failure, True is not false.
  • build 3445 (first build with GH-160028): timeout (45.1 seconds). Every build since fails the same way, e.g. build 3523.

AMD64 Alpine Linux 3.15:

  • build 800 (before GH-160080): only test_lazy_import fails.
  • build 815 (first build with GH-160080) and every build since, including build 851 just before v3.15.2 was tagged: this test fails too.

This failure is separate from the test_lazy_import crash on Alpine (gh-159535). The Alpine builders will stay red after that crash is fixed.

Cause

The new _wait_for_process_exec() helper waits until os.path.basename(os.readlink(f"/proc/{pid}/exe")) == "sleep". When sleep is a multicall binary, /proc/{pid}/exe points to the multicall binary instead:

System /usr/bin/sleep or /bin/sleep /proc/{pid}/exe of a running sleep
Alpine 3.24 (BusyBox) symlink to /bin/busybox /bin/busybox
RHEL UBI9 (coreutils-single, the image default) shebang script #!/usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/coreutils
RHEL UBI9 after dnf swap coreutils-single coreutils regular binary /usr/bin/sleep

The condition never becomes true, so the test always times out.

Reproducer, tested in python:3-alpine and registry.access.redhat.com/ubi9/ubi:

import os, subprocess, time
proc = subprocess.Popen(["sleep", "10"])
time.sleep(0.5)
print(os.readlink(f"/proc/{proc.pid}/exe"))
proc.kill()
Suggested fix

The helper only needs to know that the child has called exec(). The program name doesn't matter. Before exec(), the forked child's /proc/{pid}/exe is the parent's Python executable, so wait until it differs from the parent's:

-def _wait_for_process_exec(proc, name, timeout):
+def _wait_for_process_exec(proc, timeout):
     # Wait until a child process calls exec() to replace the forked process
-    # executable. Raise AssertionError on timeout.
+    # executable. Don't check the executable name: it can be a multicall
+    # binary such as /bin/busybox. Raise AssertionError on timeout.
+    parent_exe = os.readlink("/proc/self/exe")
     for _ in sleeping_retry(timeout, max_delay=0.1):
         exe = os.readlink(f"/proc/{proc.pid}/exe")
-        if os.path.basename(exe) == name:
+        if exe != parent_exe:
             break
-            _wait_for_process_exec(proc, "sleep", SHORT_TIMEOUT)
+            _wait_for_process_exec(proc, SHORT_TIMEOUT)

I tested this check with the reproducer on Alpine (BusyBox) and on UBI9 with both coreutils-single and coreutils. It detects the exec() in all three cases, while the current name check fails on Alpine and on UBI9 with coreutils-single.

CPython versions tested on:

3.15.2, CPython main branch

Operating systems tested on:

Linux (Alpine 3.24 buildbots, RHEL UBI9 container)

CPython versions tested on:

3.15

Operating systems tested on:

Linux

Linked PRs
  • gh-160901
Lenguaje dominante
Python
Estrellas
77.8k
Forks
37.7k
Merge medio
11 h 25 min
PR fusionados (30 d)
723

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de python/cpython

Todos los issues de python/cpython

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.