Skip to content

GH-148047: Check early whether tail-calling is possible for MSVC builds on Windows#148036

Merged
itamaro merged 5 commits intopython:mainfrom
chris-eibl:CheckTailCalling
Apr 12, 2026
Merged

GH-148047: Check early whether tail-calling is possible for MSVC builds on Windows#148036
itamaro merged 5 commits intopython:mainfrom
chris-eibl:CheckTailCalling

Conversation

@chris-eibl
Copy link
Copy Markdown
Member

@chris-eibl chris-eibl commented Apr 3, 2026

Rather than failing late when compiling e.g. a debug configuration

build.bat -c debug --tail-call-interp

with hundreds of

error C4737: Unable to perform required tail call. Performance may be degraded.

lets fail early with an explicit error message for configurations that are not supported by MSVC.

This is a follow-up on #140513 / #140548.

@chris-eibl
Copy link
Copy Markdown
Member Author

chris-eibl commented Apr 3, 2026

TSan https://github.com/python/cpython/actions/runs/23948631142/job/69850491565?pr=148036 failure for sure unreleated: this is a pure Windows change and would result in a build error on onsupported (Windows) hosts when using --tail-call-interp. Note that there are no such hosts in CI nor in buildbots, and if there were, they would have already failed (but with tons of Unable to perform required tail call messages).

I've checked manually that I get all the expected errors for unsupported configurations.

@Fidget-Spinner
Copy link
Copy Markdown
Member

Please open a separate issue for this, rather than reusing the same closed issue. Thanks!

@chris-eibl chris-eibl changed the title GH-139922: Check early whether tail calling is possible GH-148047: Check early whether tail calling is possible Apr 3, 2026
@chris-eibl chris-eibl added OS-windows build The build process and cross-build and removed skip news labels Apr 3, 2026
@chris-eibl chris-eibl changed the title GH-148047: Check early whether tail calling is possible GH-148047: Check early whether tail-calling is possible for MSVC builds on Windows Apr 3, 2026
Copy link
Copy Markdown
Contributor

@itamaro itamaro left a comment

Choose a reason for hiding this comment

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

Overall looks good, thank you for this!

Comment thread PCbuild/pythoncore.vcxproj
Comment thread PCbuild/pythoncore.vcxproj
Comment thread Misc/NEWS.d/next/Build/2026-04-03-20-09-46.gh-issue-148047.HE6iGK.rst Outdated
@bedevere-app
Copy link
Copy Markdown

bedevere-app bot commented Apr 4, 2026

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@itamaro itamaro merged commit cbd81d5 into python:main Apr 12, 2026
54 of 55 checks passed
@bedevere-bot
Copy link
Copy Markdown

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

Hi! The buildbot x86 Debian Installed with X 3.x (no tier) has failed when building commit cbd81d5.

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/1244/builds/7983) and take a look at the build logs.
  4. Check if the failure is related to this commit (cbd81d5) 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/1244/builds/7983

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

==

Click to see traceback logs
Traceback (most recent call last):
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/contextlib.py"�[0m, line �[35m85�[0m, in �[35minner�[0m
    return func(*args, **kwds)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/test/_test_multiprocessing.py"�[0m, line �[35m649�[0m, in �[35mtest_interrupt�[0m
    exitcode = self._kill_process(multiprocessing.Process.interrupt)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/contextlib.py"�[0m, line �[35m85�[0m, in �[35minner�[0m
    return func(*args, **kwds)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/test/_test_multiprocessing.py"�[0m, line �[35m630�[0m, in �[35m_kill_process�[0m
    self.assertEqual(�[31mjoin�[0m�[1;31m()�[0m, None)
                     �[31m~~~~�[0m�[1;31m^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/test/_test_multiprocessing.py"�[0m, line �[35m303�[0m, in �[35m__call__�[0m
    return �[31mself.func�[0m�[1;31m(*args, **kwds)�[0m
           �[31m~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/multiprocessing/process.py"�[0m, line �[35m156�[0m, in �[35mjoin�[0m
    res = self._popen.wait(timeout)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/multiprocessing/popen_fork.py"�[0m, line �[35m44�[0m, in �[35mwait�[0m
    return �[31mself.poll�[0m�[1;31m(os.WNOHANG if timeout == 0.0 else 0)�[0m
           �[31m~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/multiprocessing/popen_fork.py"�[0m, line �[35m28�[0m, in �[35mpoll�[0m
    pid, sts = �[31mos.waitpid�[0m�[1;31m(self.pid, flag)�[0m
               �[31m~~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/test/_test_multiprocessing.py"�[0m, line �[35m626�[0m, in �[35mhandler�[0m
    raise RuntimeError('join took too long: %s' % p)
�[1;35mRuntimeError�[0m: �[35mjoin took too long: <Process name='Process-158' pid=28453 parent=26696 started daemon>�[0m


Traceback (most recent call last):
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/contextlib.py"�[0m, line �[35m85�[0m, in �[35minner�[0m
    return func(*args, **kwds)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/test/_test_multiprocessing.py"�[0m, line �[35m649�[0m, in �[35mtest_interrupt�[0m
    exitcode = self._kill_process(multiprocessing.Process.interrupt)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/contextlib.py"�[0m, line �[35m85�[0m, in �[35minner�[0m
    return func(*args, **kwds)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/test/_test_multiprocessing.py"�[0m, line �[35m630�[0m, in �[35m_kill_process�[0m
    self.assertEqual(�[31mjoin�[0m�[1;31m()�[0m, None)
                     �[31m~~~~�[0m�[1;31m^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/test/_test_multiprocessing.py"�[0m, line �[35m303�[0m, in �[35m__call__�[0m
    return �[31mself.func�[0m�[1;31m(*args, **kwds)�[0m
           �[31m~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/multiprocessing/process.py"�[0m, line �[35m156�[0m, in �[35mjoin�[0m
    res = self._popen.wait(timeout)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/multiprocessing/popen_fork.py"�[0m, line �[35m44�[0m, in �[35mwait�[0m
    return �[31mself.poll�[0m�[1;31m(os.WNOHANG if timeout == 0.0 else 0)�[0m
           �[31m~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/multiprocessing/popen_fork.py"�[0m, line �[35m28�[0m, in �[35mpoll�[0m
    pid, sts = �[31mos.waitpid�[0m�[1;31m(self.pid, flag)�[0m
               �[31m~~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.15/test/_test_multiprocessing.py"�[0m, line �[35m626�[0m, in �[35mhandler�[0m
    raise RuntimeError('join took too long: %s' % p)
�[1;35mRuntimeError�[0m: �[35mjoin took too long: <Process name='Process-1' pid=2089 parent=2087 started daemon>�[0m

@chris-eibl chris-eibl deleted the CheckTailCalling branch April 12, 2026 05:58
<Error Text="MSVC supports tail-calling only for x64."
Condition="$(Platform) != 'x64'" />
<Error Text="Platform toolset >= v145 is required for tail-calling."
Condition="$(PlatformToolset.Replace('v', '0')) &lt; '145'" />
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.

We can't do this check - PlatformToolset is an arbitrary string, you can't assume that it's comparable to a number in any meaningful way.

<Error Text="Platform toolset >= v145 is required for tail-calling."
Condition="$(PlatformToolset.Replace('v', '0')) &lt; '145'" />
<Error Text="MSVC requires optimization to be enabled for tail-calling."
Condition="$(Configuration) == 'Debug'" />
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.

Why would we do this? It makes it annoyingly hard to set tail calling enabled in my environment and then choose between debug/release builds.

A warning is fine, if you really want, but a debug build is inherently without optimisations, so there's no reason to remind users that that's what they're getting.


<Target Name="_CheckTailCalling" BeforeTargets="PrepareForBuild" Condition="'$(UseTailCallInterp)' == 'true' and $(PlatformToolset) != 'ClangCL'">
<Error Text="MSVC supports tail-calling only for x64."
Condition="$(Platform) != 'x64'" />
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.

Not convinced this needs to be an error - if/when MSVC gets support, they may want to test it on CPython themselves before shipping, and we're just going to block them.

As with Debug, make it a warning if you really want, but ultimately it's up to the user to decide whether they're enabling a feature or not. We shouldn't prevent users from doing what they want to do.

@Fidget-Spinner
Copy link
Copy Markdown
Member

Really sorry @chris-eibl, but I'm going to revert this change. I think users can just let the compiler fail to build if it's not available.

Fidget-Spinner added a commit to Fidget-Spinner/cpython that referenced this pull request Apr 14, 2026
@Fidget-Spinner
Copy link
Copy Markdown
Member

Revert up at #148558

@chris-eibl
Copy link
Copy Markdown
Member Author

Really sorry @chris-eibl, but I'm going to revert this change. I think users can just let the compiler fail to build if it's not available.

No worries, totally fine with me. That's why we have discussions and reviews.

Sorry for the churn.

@Fidget-Spinner
Copy link
Copy Markdown
Member

No problem, nothing to apologise for!

Fidget-Spinner added a commit that referenced this pull request Apr 14, 2026
…sible for MSVC builds on Windows (#148036)" (#148558)

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

Labels

build The build process and cross-build OS-windows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants