#1150306 python-psutil: FTBFS: racy tests

#1150306#5
Date:
2026-10-08 12:29:47 UTC
From:
To:
Dear maintainer:

During a rebuild of all packages in unstable, this package failed to build.

The failures do not happen always, but the failure rate is higher on single-cpu
systems, so I recommend GRUB_CMDLINE_LINUX="nr_cpus=1" to reproduce. If this
is not enough, I can offer a VM to reproduce, as always.

I've put several build logs here for reference:

https://people.debian.org/~sanvila/build-logs/202610/

Note that the failing tests are not always the same, but there are four or them
which happen often enough:

FAILED tests/test_process.py::TestProcess::test_long_cmdline
FAILED tests/test_unicode.py::TestFSAPIsWithInvalidPath::test_proc_name
FAILED tests/test_unicode.py::TestFSAPIsWithInvalidPath::test_proc_cmdline
FAILED tests/test_unicode.py::TestFSAPIsWithInvalidPath::test_proc_exe

I see there is already a bunch of tests being skipped in debian/rules
for several reasons, so I propose that we do the same for those four tests,
as in the attached patch (where NNNNNNN is to be replaced by the actual bug number).

Thanks.
--------------------------------------------------------------------------------
[...]
tests/test_windows.py::RemoteProcessTestCase::test_environ_64 SKIPPED
tests/test_windows.py::TestServices::test_win_service_get SKIPPED
tests/test_windows.py::TestServices::test_win_service_iter SKIPPED

=========================== short test summary info ============================
FAILED tests/test_process.py::TestProcess::test_long_cmdline - AssertionError: assert ['-m', 'pytest', '--verbose', '--ignore=tests/test_memleaks.py', '-k', '    not test_disk_partition and not test_import_all and not test_against_findmnt and not test_comparisons and not test_who and not test_invocation and not test_users and not test_procsmem and not test_all and not test_sensors_temperatures and not test_ips and not test_emulate_use_cpuinfo and not test_emulate_use_second_file and not test_cpu_freq and not test_against_nproc and not test_cpu_freq and not test_cpu_affinity '] == ['-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-v', '-c', 'import time; [time.sleep(0.1) for x in range(100)]']

   At index 0 diff: '-m' != '-v'
   Right contains 46 more items, first extra item: '-v'

   Full diff:
     [
   -     '-v',
   ?       ^
   +     '-m',
   ?       ^
   +     'pytest',
   +     '--verbose',
   +     '--ignore=tests/test_memleaks.py',
   -     '-v',
   ?       ^
   +     '-k',
   ?       ^
   +     '    not test_disk_partition and not test_import_all and not '
   +     'test_against_findmnt and not test_comparisons and not test_who and not '
   +     'test_invocation and not test_users and not test_procsmem and not test_all '
   +     'and not test_sensors_temperatures and not test_ips and not '
   +     'test_emulate_use_cpuinfo and not test_emulate_use_second_file and not '
   +     'test_cpu_freq and not test_against_nproc and not test_cpu_freq and not '
   +     'test_cpu_affinity ',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-v',
   -     '-c',
   -     'import time; [time.sleep(0.1) for x in range(100)]',
     ]
FAILED tests/test_unicode.py::TestFSAPIsWithInvalidPath::test_proc_cmdline - AssertionError: assert ['python3.14', '-m', 'pytest', '--verbose', '--ignore=tests/test_memleaks.py', '-k', '    not test_disk_partition and not test_import_all and not test_against_findmnt and not test_comparisons and not test_who and not test_invocation and not test_users and not test_procsmem and not test_all and not test_sensors_temperatures and not test_ips and not test_emulate_use_cpuinfo and not test_emulate_use_second_file and not test_cpu_freq and not test_against_nproc and not test_cpu_freq and not test_cpu_affinity '] == ['/tmp/@psutil-147-02nz6vuqf\udcc0\udc80', '-c', 'import time; [time.sleep(0.1) for x in range(100)]']

   At index 0 diff: 'python3.14' != '/tmp/@psutil-147-02nz6vuqf\udcc0\udc80'
   Left contains 4 more items, first extra item: '--verbose'

   Full diff:
     [
   -     '/tmp/@psutil-147-02nz6vuqf\udcc0\udc80',
   +     'python3.14',
   -     '-c',
   ?       ^
   +     '-m',
   ?       ^
   -     'import time; [time.sleep(0.1) for x in range(100)]',
   +     'pytest',
   +     '--verbose',
   +     '--ignore=tests/test_memleaks.py',
   +     '-k',
   +     '    not test_disk_partition and not test_import_all and not '
   +     'test_against_findmnt and not test_comparisons and not test_who and not '
   +     'test_invocation and not test_users and not test_procsmem and not test_all '
   +     'and not test_sensors_temperatures and not test_ips and not '
   +     'test_emulate_use_cpuinfo and not test_emulate_use_second_file and not '
   +     'test_cpu_freq and not test_against_nproc and not test_cpu_freq and not '
   +     'test_cpu_affinity ',
     ]
FAILED tests/test_unicode.py::TestFSAPIsWithInvalidPath::test_proc_exe - AssertionError: assert '/usr/bin/python3.14' == '/tmp/@psutil-147-02nz6vuqf\udcc0\udc80'

   - /tmp/@psutil-147-02nz6vuqf��
   + /usr/bin/python3.14
FAILED tests/test_unicode.py::TestFSAPIsWithInvalidPath::test_proc_name - AssertionError: assert 'python3.14' == '@psutil-147-02nz6vuqf\udcc0\udc80'

   - @psutil-147-02nz6vuqf��
   + python3.14
========== 4 failed, 395 passed, 161 skipped, 38 deselected in 5.02s ===========
E: pybuild pybuild:485: test: plugin pyproject failed with: exit code=1: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.14/build; python3.14 -m pytest --verbose --ignore=tests/test_memleaks.py -k '    not test_disk_partition and not test_import_all and not test_against_findmnt and not test_comparisons and not test_who and not test_invocation and not test_users and not test_procsmem and not test_all and not test_sensors_temperatures and not test_ips and not test_emulate_use_cpuinfo and not test_emulate_use_second_file and not test_cpu_freq and not test_against_nproc and not test_cpu_freq and not test_cpu_affinity '
dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p 3.14 --parallel=1 returned exit code 13
make: *** [debian/rules:37: binary] Error 25
dpkg-buildpackage: error: debian/rules binary subprocess failed with exit status 2
--------------------------------------------------------------------------------

#1150306#10
Date:
2026-10-08 12:41:29 UTC
From:
To:

first = {'/tmp/datalad_temp_tree_test_get_open_fileswasnd43a/d': psutil.Process(pid=621486, name='python3.14', status='zombie')}
second = {}, msg = None

    def assert_equal(first, second, msg=None):
        if msg is None:
E           AssertionError: assert {'/tmp/datala...us='running')} == {}
E
E             Left contains 1 more item:
E             {'/tmp/datalad_temp_tree_test_get_open_fileswasnd43a/d': psutil.Process(pid=621486, name='python3.14', status='running')}
E
E             Full diff:
E             - {}
E             + {
E             +     '/tmp/datalad_temp_tree_test_get_open_fileswasnd43a/d': psutil.Process(pid=621486, name='python3.14', status='running'),
E             + }

datalad/tests/utils_pytest.py:89: AssertionError


Looks like a race condition similar to the one in python-psutil, so I
wonder if those two issues are related. It might be worth to forward
the bug upstream, because at this point we don't know if the test
failure means the test is wrongly designed or it's a real bug in the
program.

Thanks.

#1150306#15
Date:
2026-10-17 22:19:52 UTC
From:
To:
We believe that the bug you reported is fixed in the latest version of
python-psutil, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 1150306@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Sandro Tosi <morph@debian.org> (supplier of updated python-psutil package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@ftp-master.debian.org)
Format: 1.8
Date: Sat, 17 Oct 2026 18:04:44 -0400
Source: python-psutil
Architecture: source
Version: 7.2.2-2
Distribution: unstable
Urgency: medium
Maintainer: Sandro Tosi <morph@debian.org>
Changed-By: Sandro Tosi <morph@debian.org>
Closes: 1150306
Changes:
 python-psutil (7.2.2-2) unstable; urgency=medium
 .
   * debian/patches/*
     - backport upstream fixes for the flaky test_cmdline and drop the flaky
       test_long_cmdline; make the unicode process tests wait for the child
       to exec, too; Closes: #1150306
     - backport upstream fix for Process.wait() raising EINVAL from
       pidfd_open() on Linux
     - backport upstream fix for test_interrupts on 32-bit architectures, and
       don't assume the inherited I/O class in test_ionice_linux; fix the
       rebuilds on reproduce.debian.net
   * debian/control
     - drop the relationship substvars, now applied automatically
     - switch Testsuite to autopkgtest-pkg-pybuild, to run the upstream tests
     - refresh the description from upstream README
   * debian/rules
     - drop overrides of dh_installchangelogs, dh_installdocs and dh_compress,
       debhelper defaults now do the same
     - drop the duplicate test_cpu_freq from the skipped tests
   * debian/copyright
     - point Source to GitHub, where the tarball comes from
     - add missing copyright holders
   * debian/upstream/metadata
     - add Changelog and Documentation
Checksums-Sha1:
 431517c79226b38652b5cefbeeb99f3ab16faf39 2173 python-psutil_7.2.2-2.dsc
 9643c0a64302f6a595977216168e9db9a2161110 11156 python-psutil_7.2.2-2.debian.tar.xz
 699b7add03d765300a4af8ba9c88507c146e1a61 8698 python-psutil_7.2.2-2_source.buildinfo
Checksums-Sha256:
 7ed45b175e5d88bae7575597d09961db5c2987d951a2697f46d6ff2857e96293 2173 python-psutil_7.2.2-2.dsc
 4396b96392ee85efd1afd2f4c496c74ea7b00c889ba83ba78038222f899ec080 11156 python-psutil_7.2.2-2.debian.tar.xz
 baacaa38c7b108d41add4557780d8bb1055f9b99cb21242dad5ed1abbb1a48d7 8698 python-psutil_7.2.2-2_source.buildinfo
Files:
 781a5fb972236a97bc3e1b2cde02a89d 2173 python optional python-psutil_7.2.2-2.dsc
 ca9ef3c1034cfaba8e8cf2efa7219799 11156 python optional python-psutil_7.2.2-2.debian.tar.xz
 9b4f63fda5b13f095d012ce4b531a02c 8698 python optional python-psutil_7.2.2-2_source.buildinfo
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEufrTGSrz5KUwnZ05h588mTgBqU8FAmrT8QYACgkQh588mTgB
qU+zxg/7ByjVUzp7ttRBTy7IliOpVtJhszSoSZkZtSFUq4zc6qFDZIZQ0FnuACdi
JnrcHc5+tyE9sYc0VqmOwo4Ngn0m7IOpeIGyxvr3wh8ZQTjFuKp9LFbPW2+P28CZ
C9gWmk7feO3Ym1Cn4/b2Gnpa14Vlo4nVnTn8PiGCl+35LAdYBssxUnlGNCnXlAUw
/nqItzeVWHnYLVvWr2ui0L4WrRvUlB9oaknTC10UWnx0MLtJXpQBVJiuVRB+YmfJ
e5px4nsLldLoJMUNOmfotJ7DS9VKl1bGNrvRPF6EpgkeitIO2TCgvPc/CGgzSmh2
OUhcMKU9bZcWTFzL0ILa65kmNT6WoXMU8deiHicCl86UbeoJKTCHg8Zur7DukzJ/
n2a5x8M8cTouGW2DLAOOgRHIVohttsaaLCvHaXqtK3GJ0gz8m4jFq9j0IEV5LraZ
NFg8z5hslOkq51XrsGXlHazHpuAvJeTu9X8O/GZ2cpvmNv4mDDB4FKpBkCmC3NQS
6KXLPVjfDAShycjzEGY7B8sl8b4RIIo8sZBjUggrQwDycoZGyAyZJJl5VOpV2gYH
ZYlxQoTJbG8wAjUEmHm6eFaJje3LeCt9t0lUfmWYBqBSIwvMloQkvhzVd4wfzhoB
3aTcyNAkt9zfLuNO6XGmLIvIvVmZCUwadkUJNrxDAGz2VjnqcaM=
=Qv33
-----END PGP SIGNATURE-----