diff --git a/.hgignore b/.hgignore
index c67ffb8cbc6..4dc93c47232 100644
--- a/.hgignore
+++ b/.hgignore
@@ -18,6 +18,7 @@ db_home
platform$
pyconfig.h$
python$
+python.bat$
python.exe$
python-config$
python-config.py$
diff --git a/Misc/NEWS b/Misc/NEWS
index dc3a5832206..b2f8cdec90c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -322,6 +322,10 @@ IDLE
Build
-----
+- Issue #19962: The Windows build process now creates "python.bat" in the
+ root of the source tree, which passes all arguments through to the most
+ recently built interpreter.
+
- Issue #21285: Refactor and fix curses configure check to always search
in a ncursesw directory.
diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj
index bd126245963..538734367ba 100644
--- a/PCbuild/python.vcxproj
+++ b/PCbuild/python.vcxproj
@@ -156,6 +156,14 @@
AllRules.ruleset
+ Link
+ Link
+ Link
+ Link
+ Link
+ Link
+ Link
+ Link
@@ -176,6 +184,25 @@
2000000
0x1d000000
+
+ echo @rem This script invokes the most recently built Python with all arguments> "$(SolutionDir)..\python.bat"
+echo @rem passed through to the interpreter. This file is generated by the>> "$(SolutionDir)..\python.bat"
+echo @rem build process and any changes *will* be thrown away by the next>> "$(SolutionDir)..\python.bat"
+echo @rem rebuild.>> "$(SolutionDir)..\python.bat"
+echo @rem This is only meant as a convenience for developing CPython>> "$(SolutionDir)..\python.bat"
+echo @rem and using it outside of that context is ill-advised.>> "$(SolutionDir)..\python.bat"
+echo @echo Running $(Configuration)^^^|$(Platform) interpreter...>> "$(SolutionDir)..\python.bat"
+echo @"$(OutDir)python$(PyDebugExt).exe" %%*>> "$(SolutionDir)..\python.bat"
+
+
+ Creating convenience batch file for easily invoking the newly built interpreter.
+
+
+ $(SolutionDir)..\python.bat
+
+
+ $(OutDir)python$(PyDebugExt).exe;%(Inputs)
+
@@ -199,6 +226,25 @@
2000000
0x1d000000
+
+ echo @rem This script invokes the most recently built Python with all arguments> "$(SolutionDir)..\python.bat"
+echo @rem passed through to the interpreter. This file is generated by the>> "$(SolutionDir)..\python.bat"
+echo @rem build process and any changes *will* be thrown away by the next>> "$(SolutionDir)..\python.bat"
+echo @rem rebuild.>> "$(SolutionDir)..\python.bat"
+echo @rem This is only meant as a convenience for developing CPython>> "$(SolutionDir)..\python.bat"
+echo @rem and using it outside of that context is ill-advised.>> "$(SolutionDir)..\python.bat"
+echo @echo Running $(Configuration)^^^|$(Platform) interpreter...>> "$(SolutionDir)..\python.bat"
+echo @"$(OutDir)python$(PyDebugExt).exe" %%*>> "$(SolutionDir)..\python.bat"
+
+
+ Creating convenience batch file for easily invoking the newly built interpreter.
+
+
+ $(SolutionDir)..\python.bat
+
+
+ $(OutDir)python$(PyDebugExt).exe;%(Inputs)
+
@@ -221,6 +267,25 @@
2000000
0x1d000000
+
+ echo @rem This script invokes the most recently built Python with all arguments> "$(SolutionDir)..\python.bat"
+echo @rem passed through to the interpreter. This file is generated by the>> "$(SolutionDir)..\python.bat"
+echo @rem build process and any changes *will* be thrown away by the next>> "$(SolutionDir)..\python.bat"
+echo @rem rebuild.>> "$(SolutionDir)..\python.bat"
+echo @rem This is only meant as a convenience for developing CPython>> "$(SolutionDir)..\python.bat"
+echo @rem and using it outside of that context is ill-advised.>> "$(SolutionDir)..\python.bat"
+echo @echo Running $(Configuration)^^^|$(Platform) interpreter...>> "$(SolutionDir)..\python.bat"
+echo @"$(OutDir)python$(PyDebugExt).exe" %%*>> "$(SolutionDir)..\python.bat"
+
+
+ Creating convenience batch file for easily invoking the newly built interpreter.
+
+
+ $(SolutionDir)..\python.bat
+
+
+ $(OutDir)python$(PyDebugExt).exe;%(Inputs)
+
@@ -246,6 +311,25 @@
4194304
0x1d000000
+
+ echo @rem This script invokes the most recently built Python with all arguments> "$(SolutionDir)..\python.bat"
+echo @rem passed through to the interpreter. This file is generated by the>> "$(SolutionDir)..\python.bat"
+echo @rem build process and any changes *will* be thrown away by the next>> "$(SolutionDir)..\python.bat"
+echo @rem rebuild.>> "$(SolutionDir)..\python.bat"
+echo @rem This is only meant as a convenience for developing CPython>> "$(SolutionDir)..\python.bat"
+echo @rem and using it outside of that context is ill-advised.>> "$(SolutionDir)..\python.bat"
+echo @echo Running $(Configuration)^^^|$(Platform) interpreter...>> "$(SolutionDir)..\python.bat"
+echo @"$(OutDir)python$(PyDebugExt).exe" %%*>> "$(SolutionDir)..\python.bat"
+
+
+ Creating convenience batch file for easily invoking the newly built interpreter.
+
+
+ $(SolutionDir)..\python.bat
+
+
+ $(OutDir)python$(PyDebugExt).exe;%(Inputs)
+
@@ -268,6 +352,25 @@
+
+ echo @rem This script invokes the most recently built Python with all arguments> "$(SolutionDir)..\python.bat"
+echo @rem passed through to the interpreter. This file is generated by the>> "$(SolutionDir)..\python.bat"
+echo @rem build process and any changes *will* be thrown away by the next>> "$(SolutionDir)..\python.bat"
+echo @rem rebuild.>> "$(SolutionDir)..\python.bat"
+echo @rem This is only meant as a convenience for developing CPython>> "$(SolutionDir)..\python.bat"
+echo @rem and using it outside of that context is ill-advised.>> "$(SolutionDir)..\python.bat"
+echo @echo Running $(Configuration)^^^|$(Platform) interpreter...>> "$(SolutionDir)..\python.bat"
+echo @"$(OutDir)python$(PyDebugExt).exe" %%*>> "$(SolutionDir)..\python.bat"
+
+
+ Creating convenience batch file for easily invoking the newly built interpreter.
+
+
+ $(SolutionDir)..\python.bat
+
+
+ $(OutDir)python$(PyDebugExt).exe;%(Inputs)
+
@@ -294,6 +397,25 @@
MachineX64
+
+ echo @rem This script invokes the most recently built Python with all arguments> "$(SolutionDir)..\python.bat"
+echo @rem passed through to the interpreter. This file is generated by the>> "$(SolutionDir)..\python.bat"
+echo @rem build process and any changes *will* be thrown away by the next>> "$(SolutionDir)..\python.bat"
+echo @rem rebuild.>> "$(SolutionDir)..\python.bat"
+echo @rem This is only meant as a convenience for developing CPython>> "$(SolutionDir)..\python.bat"
+echo @rem and using it outside of that context is ill-advised.>> "$(SolutionDir)..\python.bat"
+echo @echo Running $(Configuration)^^^|$(Platform) interpreter...>> "$(SolutionDir)..\python.bat"
+echo @"$(OutDir)python$(PyDebugExt).exe" %%*>> "$(SolutionDir)..\python.bat"
+
+
+ Creating convenience batch file for easily invoking the newly built interpreter.
+
+
+ $(SolutionDir)..\python.bat
+
+
+ $(OutDir)python$(PyDebugExt).exe;%(Inputs)
+
@@ -316,6 +438,25 @@
+
+ echo @rem This script invokes the most recently built Python with all arguments> "$(SolutionDir)..\python.bat"
+echo @rem passed through to the interpreter. This file is generated by the>> "$(SolutionDir)..\python.bat"
+echo @rem build process and any changes *will* be thrown away by the next>> "$(SolutionDir)..\python.bat"
+echo @rem rebuild.>> "$(SolutionDir)..\python.bat"
+echo @rem This is only meant as a convenience for developing CPython>> "$(SolutionDir)..\python.bat"
+echo @rem and using it outside of that context is ill-advised.>> "$(SolutionDir)..\python.bat"
+echo @echo Running $(Configuration)^^^|$(Platform) interpreter...>> "$(SolutionDir)..\python.bat"
+echo @"$(OutDir)python$(PyDebugExt).exe" %%*>> "$(SolutionDir)..\python.bat"
+
+
+ Creating convenience batch file for easily invoking the newly built interpreter.
+
+
+ $(SolutionDir)..\python.bat
+
+
+ $(OutDir)python$(PyDebugExt).exe;%(Inputs)
+
@@ -342,6 +483,25 @@
MachineX64
+
+ echo @rem This script invokes the most recently built Python with all arguments> "$(SolutionDir)..\python.bat"
+echo @rem passed through to the interpreter. This file is generated by the>> "$(SolutionDir)..\python.bat"
+echo @rem build process and any changes *will* be thrown away by the next>> "$(SolutionDir)..\python.bat"
+echo @rem rebuild.>> "$(SolutionDir)..\python.bat"
+echo @rem This is only meant as a convenience for developing CPython>> "$(SolutionDir)..\python.bat"
+echo @rem and using it outside of that context is ill-advised.>> "$(SolutionDir)..\python.bat"
+echo @echo Running $(Configuration)^^^|$(Platform) interpreter...>> "$(SolutionDir)..\python.bat"
+echo @"$(OutDir)python$(PyDebugExt).exe" %%*>> "$(SolutionDir)..\python.bat"
+
+
+ Creating convenience batch file for easily invoking the newly built interpreter.
+
+
+ $(SolutionDir)..\python.bat
+
+
+ $(OutDir)python$(PyDebugExt).exe;%(Inputs)
+
@@ -361,4 +521,4 @@
-
+
\ No newline at end of file