Skip to content

gh-158681: Document that regrtest rejects test_main() and loads unittest suites - #158682

Merged
StanFromIreland merged 9 commits into
python:mainfrom
bazhil:doc-regrtest-unittest-loader
Oct 16, 2026
Merged

StanFromIreland merged 9 commits into
python:mainfrom
bazhil:doc-regrtest-unittest-loader

Conversation

@bazhil

@bazhil bazhil commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

#158681

Doc/library/test.rst said that python -m test calls a module-level test_main() when it exists, and otherwise loads tests with unittest.TestLoader.loadTestsFromModule. It also told readers to call test.support.reap_children() at the end of test_main. The docstring of reap_children() said the same thing.

libregrtest does not call test_main(). If the imported module defines it, Lib/test/libregrtest/single.py raises Exception. regrtest reports the module as failed with an uncaught exception (stderr: test <name> crashed; summary: failed (uncaught exception)). Tests are loaded with loadTestsFromModule, which collects TestCase classes and, when the module defines load_tests, runs the suite that function returns. Packages use load_tests, usually via test.support.load_package_tests, to add tests from submodules. reap_children() is called from setUp(), tearDown(), and tearDownModule().

The runner is unchanged. This updates the library page and the reap_children() docstring.

@python-cla-bot

python-cla-bot Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

@read-the-docs-community

read-the-docs-community Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Comment thread Misc/NEWS.d/next/Documentation/2026-10-03-21-19-14.gh-issue-158681.fpovlg.rst Outdated
@aisk aisk added the skip news label Oct 4, 2026
@aisk

aisk commented Oct 4, 2026

Copy link
Copy Markdown
Member

The commit email doesn't seem to be a valid address. Please use a valid one.

@bazhil
bazhil force-pushed the doc-regrtest-unittest-loader branch from fd30727 to 58b6171 Compare October 4, 2026 16:51
@bazhil

bazhil commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor Author

The commit email doesn't seem to be a valid address. Please use a valid one.

Fixed

Comment thread Doc/library/test.rst Outdated
Comment thread Doc/library/test.rst Outdated
@bazhil
bazhil force-pushed the doc-regrtest-unittest-loader branch from 58b6171 to aabe5ea Compare October 7, 2026 21:38

@StanFromIreland StanFromIreland left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some suggested wording tweaks.

Comment thread Lib/test/support/__init__.py Outdated
Comment on lines 1598 to 1602
"""Call this from a test's setUp(), tearDown(), or tearDownModule()
when the test starts subprocesses. This will help ensure that no extra
children (zombies) stick around to hog resources and create problems when
looking for refleaks.
"""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Call this from a test's setUp(), tearDown(), or tearDownModule()
when the test starts subprocesses. This will help ensure that no extra
children (zombies) stick around to hog resources and create problems when
looking for refleaks.
"""
"""Call this from setUp(), tearDown(), or tearDownModule() in tests
that start subprocesses. This will help ensure that no extra children
(zombies) stick around to hog resources and create problems when
looking for refleaks.
"""

Comment thread Doc/library/test.rst Outdated
Comment on lines +888 to +892
Call this from a test's :meth:`~unittest.TestCase.setUp`,
:meth:`~unittest.TestCase.tearDown`, or ``tearDownModule`` when the
test starts subprocesses. This will help ensure that no extra children
(zombies) stick around to hog resources and create problems when looking
for refleaks.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Call this from a test's :meth:`~unittest.TestCase.setUp`,
:meth:`~unittest.TestCase.tearDown`, or ``tearDownModule`` when the
test starts subprocesses. This will help ensure that no extra children
(zombies) stick around to hog resources and create problems when looking
for refleaks.
Call this from :meth:`~unittest.TestCase.setUp`,
:meth:`~unittest.TestCase.tearDown`, or ``tearDownModule()`` in tests
that start subprocesses. This will help ensure that no extra children
(zombies) stick around to hog resources and create problems when looking
for refleaks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment thread Doc/library/test.rst Outdated
Comment on lines +168 to +175
:mod:`!test` package. It does this by finding modules and packages whose names
start with ``test_``, importing each one, and loading its tests with
:meth:`unittest.TestLoader.loadTestsFromModule`. See the
:ref:`load_tests protocol <load_tests-protocol>` for how a module or package
can customize what is loaded. A module-level ``test_main()`` function is not
called. If a test module defines ``test_main``, :mod:`!test.regrtest` fails
that test. The names of
tests to execute may also be passed to the script. Specifying a single

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:mod:`!test` package. It does this by finding modules and packages whose names
start with ``test_``, importing each one, and loading its tests with
:meth:`unittest.TestLoader.loadTestsFromModule`. See the
:ref:`load_tests protocol <load_tests-protocol>` for how a module or package
can customize what is loaded. A module-level ``test_main()`` function is not
called. If a test module defines ``test_main``, :mod:`!test.regrtest` fails
that test. The names of
tests to execute may also be passed to the script. Specifying a single
:mod:`!test` package. It does this by finding modules and packages whose names
start with ``test_``, importing each one, and loading its tests with
:meth:`unittest.TestLoader.loadTestsFromModule`. See the
:ref:`load_tests protocol <load_tests-protocol>` for how a module or package
can customize what is loaded. Defining a module-level ``test_main()`` function
is not supported and causes the test to fail. The names of tests to
execute may also be passed to the script. Specifying a single

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@StanFromIreland

Copy link
Copy Markdown
Member

Please don't force push.

Also please apply suggestions, as it is clearer for reviewers whether something as been resolved (and if it has been modified while doing so).

@StanFromIreland

Copy link
Copy Markdown
Member

@bazhil please apply suggestions via the web interface, that way it's clear if they have been applied or not. Since you didn't do that, I now have to re-review again.

@bazhil

bazhil commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

@StanFromIreland I apologize for the inconvenience. I will proceed in exactly this way in the future.

@StanFromIreland
StanFromIreland merged commit 75ce53d into python:main Oct 16, 2026
56 checks passed
@StanFromIreland StanFromIreland added the needs backport to 3.14 bugs and security fixes label Oct 16, 2026
@StanFromIreland StanFromIreland added the needs backport to 3.15 bugs and security fixes label Oct 16, 2026
@miss-islington-app

Copy link
Copy Markdown

Thanks @bazhil for the PR, and @StanFromIreland for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

@miss-islington-app

Copy link
Copy Markdown

Thanks @bazhil for the PR, and @StanFromIreland for merging it 🌮🎉.. I'm working now to backport this PR to: 3.15.
🐍🍒⛏🤖

@bedevere-app

bedevere-app Bot commented Oct 16, 2026

Copy link
Copy Markdown

GH-159574 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label Oct 16, 2026
@bedevere-app

bedevere-app Bot commented Oct 16, 2026

Copy link
Copy Markdown

GH-159575 is a backport of this pull request to the 3.15 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 bugs and security fixes label Oct 16, 2026
@bazhil

bazhil commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

@aisk @StanFromIreland Thank you!

StanFromIreland pushed a commit that referenced this pull request Oct 16, 2026
…n()` (GH-158682) (#159574)

(cherry picked from commit 75ce53d)

Co-authored-by: Ilya Bazhenov <31971067+bazhil@users.noreply.github.com>
StanFromIreland pushed a commit that referenced this pull request Oct 16, 2026
…n()` (GH-158682) (#159575)

(cherry picked from commit 75ce53d)

Co-authored-by: Ilya Bazhenov <31971067+bazhil@users.noreply.github.com>
@bedevere-bot

Copy link
Copy Markdown

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot ARM64 Raspbian 3.15 (tier-3) has failed when building commit df75ad4.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/2033/builds/609) and take a look at the build logs.
  4. Check if the failure is related to this commit (df75ad4) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/2033/builds/609

Failed tests:

  • test.test_multiprocessing_fork.test_processes

Failed subtests:

  • test_interrupt - test.test_multiprocessing_fork.test_processes.WithProcessesTestProcess.test_interrupt

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/contextlib.py", line 116, in inner
    return func(*args, **kwds)
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/test/_test_multiprocessing.py", line 650, in test_interrupt
    exitcode = self._kill_process(multiprocessing.Process.interrupt)
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/contextlib.py", line 116, in inner
    return func(*args, **kwds)
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/test/_test_multiprocessing.py", line 631, in _kill_process
    self.assertEqual(join(), None)
                     ~~~~^^
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/test/_test_multiprocessing.py", line 304, in __call__
    return self.func(*args, **kwds)
           ~~~~~~~~~^^^^^^^^^^^^^^^
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/multiprocessing/process.py", line 156, in join
    res = self._popen.wait(timeout)
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/multiprocessing/popen_fork.py", line 44, in wait
    return self.poll(os.WNOHANG if timeout == 0.0 else 0)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/multiprocessing/popen_fork.py", line 28, in poll
    pid, sts = os.waitpid(self.pid, flag)
               ~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/test/_test_multiprocessing.py", line 627, in handler
    raise RuntimeError('join took too long: %s' % p)
RuntimeError: join took too long: <Process name='Process-1' pid=1359989 parent=1359987 started daemon>


Traceback (most recent call last):
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/contextlib.py", line 116, in inner
    return func(*args, **kwds)
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/test/_test_multiprocessing.py", line 650, in test_interrupt
    exitcode = self._kill_process(multiprocessing.Process.interrupt)
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/contextlib.py", line 116, in inner
    return func(*args, **kwds)
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/test/_test_multiprocessing.py", line 631, in _kill_process
    self.assertEqual(join(), None)
                     ~~~~^^
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/test/_test_multiprocessing.py", line 304, in __call__
    return self.func(*args, **kwds)
           ~~~~~~~~~^^^^^^^^^^^^^^^
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/multiprocessing/process.py", line 156, in join
    res = self._popen.wait(timeout)
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/multiprocessing/popen_fork.py", line 44, in wait
    return self.poll(os.WNOHANG if timeout == 0.0 else 0)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/multiprocessing/popen_fork.py", line 28, in poll
    pid, sts = os.waitpid(self.pid, flag)
               ~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/home/stan/buildarea/3.15.stan-raspbian.nondebug/build/Lib/test/_test_multiprocessing.py", line 627, in handler
    raise RuntimeError('join took too long: %s' % p)
RuntimeError: join took too long: <Process name='Process-152' pid=1358143 parent=1357456 started daemon>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants