These instructions cover how to get a working copy of the source code and acompiled version of the CPython interpreter (CPython is the version of Pythonavailable fromhttps://www.python.org/). It also gives an overview of thedirectory structure of the CPython source code.
Alternatively, if you haveDocker installed youmight want to useour official images. Thesecontain the latest releases of several Python versions, along with Git head,and are provided for development and testing purposes only.
See also
TheQuick reference gives brief summary of the process frominstalling Git to submitting a pull request.
CPython is developed usingGit for version control. The Gitcommand line program is namedgit
; this is also used to refer to Gititself. Git is easily available for all common operating systems.
Install
As the CPython repo is hosted on GitHub, please refer to either theGitHub setup instructionsor theGit project instructions for step-by-stepinstallation directions. You may also want to consider a graphical clientsuch asTortoiseGit orGitHub Desktop.
Configure
Configureyour name and email and createan SSH keyas this will allow you to interact with GitHub without typing a usernameand password each time you execute a command, such asgitpull
,gitpush
, orgitfetch
. On Windows, you should alsoenable autocrlf.
The CPython repo is hosted on GitHub. To get a copy of the source code you shouldfork the Python repository on GitHub,create a localclone of your personal fork, and configure the remotes.
You will only need to execute these steps once per machine:
PressFork on the top right.
When asked where to fork the repository, choose to fork it to your username.
Your fork will be created athttps://github.com/<username>/cpython
.
Clone your GitHub fork (replace<username>
with your username):
$gitclonegit@github.com:<username>/cpython.git
(You can use both SSH-based or HTTPS-based URLs.)
Add anupstream
remote, then configuregit
to pullmain
fromupstream
and always push toorigin
:
$cdcpython$gitremoteaddupstreamhttps://github.com/python/cpython$gitconfig--localbranch.main.remoteupstream$gitremoteset-url--pushupstreamgit@github.com:<your-username>/cpython.git
Verify that your setup is correct:
$gitremote-vorigin git@github.com:<your-username>/cpython.git (fetch)origin git@github.com:<your-username>/cpython.git (push)upstream https://github.com/python/cpython (fetch)upstream git@github.com:<your-username>/cpython.git (push)$gitconfigbranch.main.remoteupstream
For more information about these commands seeGit Bootcamp and Cheat Sheet.
If you did everything correctly, you should now have a copy of the codein thecpython
directory and two remotes that refer to your own GitHub fork(origin
) and the official CPython repository (upstream
).
If you want a working copy of an already-released version of Python,that is, a version inmaintenance mode, you can checkouta release branch. For instance, to checkout a working copy of Python 3.13,dogitswitch3.13
.
You will need to re-compile CPython when you do such an update.
Do note that CPython will notice that it is being run from a working copy.This means that if you edit CPython’s source code in your working copy,changes to Python code will be picked up by the interpreter for immediateuse and testing. (If you change C code, you will need to recompile theaffected files as described below.)
Changes for the documentation can be made from the same repository; seeGetting started.
To make sure your code is linted correctly, we recommend setting uppre-commit as a Git hook:
$pre-commitinstall--allow-missing-configpre-commit installed at .git/hooks/pre-commit
Now pre-commit will run automatically ongitcommit
.
CPython provides several compilation flags which help with debugging variousthings. While all of the known flags can be found in theMisc/SpecialBuilds.txt
file, the most critical one is thePy_DEBUG
flagwhich creates what is known as a “pydebug” build. This flag turns on variousextra sanity checks which help catch common issues. The use of the flag is socommon that turning on the flag is a basic compile option.
You should always develop under a pydebug build of CPython (the only instance ofwhen you shouldn’t is if you are taking performance measurements). Even whenworking only on pure Python code the pydebug build provides several usefulchecks that one should not skip.
See also
The effects of various configure and build flags are documented inthePython configure docs.
The core CPython interpreter only needs a C compiler to be built,however, some of the extension modules will need development headersfor additional libraries (such as thezlib
library for compression).Depending on what you intend to work on, you might need to install theseadditional requirements so that the compiled interpreter supports thedesired features.
If you want to install these optional dependencies, consult theInstall dependencies section below.
If you don’t need to install them, the basic steps for building Pythonfor development is to configure it and then compile it.
Configuration is typically:
$./configure--with-pydebug
More flags are available toconfigure
, but this is the minimum you shoulddo to get a pydebug build of CPython.
Note
You might need to runmakeclean
before or after re-runningconfigure
in a particular build directory.
Onceconfigure
is done, you can then compile CPython with:
$make-s-j$(nproc)
This will build CPython with only warnings and errors being printed tostderr. The-j
argument means thatmake will concurrently runtasks, limiting the number of parallel jobs to the number of CPU cores in yourcomputer. You can adjust the number passed to the-j
flag to changethe limit on parallel jobs, which can trade RAM usage versus compilation time.
At the end of the build you should see a success message, followedby a list of extension modules that haven’t been built because theirdependencies were missing:
The necessary bits to build these optional modules were not found:_gdbmTo find the necessary bits, look in configure.ac and config.log.Checked 106 modules (31 built-in, 74 shared, 0 n/a on macosx-13.4-arm64, 0 disabled, 1 missing, 0 failed on import)
If the build failed and you are using a C89 or C99-compliant compiler,please open a bug report on theissue tracker.
If you decide toInstall dependencies, you will need to re-run bothconfigure
andmake
.
Once CPython is done building you will then have a working buildthat can be run in-place;./python
on most machines (and what is used inall examples),./python.exe
wherever a case-insensitive filesystem is used(for example, on macOS by default), in order to avoid conflicts with thePython
directory. There is normally no need to install your built copyof Python! The interpreter will realize where it is being run fromand thus use the files found in the working copy. If you are worriedyou might accidentally install your working copy build, you can add--prefix=/tmp/python
to the configuration step. When running from yourworking directory, it is best to avoid using the--enable-shared
flagtoconfigure
; unless you are very careful, you may accidentally runwith code from an older, installed shared Python library rather than fromthe interpreter you just built.
If you are usingclang to build CPython, some flags you might want to set toquiet some standard warnings which are specifically superfluous to CPython are-Wno-unused-value-Wno-empty-body-Qunused-arguments
. You can set yourCFLAGS
environment variable to these flags when runningconfigure
.
If you are usingclang withccache, turn off the noisyparentheses-equality
warnings with the-Wno-parentheses-equality
flag.These warnings are caused by clang not having enough information to detectthat extraneous parentheses in expanded macros are valid, because thepreprocessing is done separately by ccache.
If you are using LLVM 2.8, also use the-no-integrated-as
flag in order tobuild thectypes
module (without the flag the rest of CPython willstill build properly).
If you are trying to improve CPython’s performance, you will probably wantto use an optimized build of CPython. It can take a lot longer to build CPythonwith optimizations enabled, and it’s usually not necessary to do so. However,it’s essential if you want accurate benchmark results for a proposed performanceoptimization.
For an optimized build of Python, useconfigure--enable-optimizations--with-lto
.This sets the default make targets up to enable Profile Guided Optimization (PGO)and may be used to auto-enable Link Time Optimization (LTO) on some platforms.See--enable-optimizations
and--with-lto
to learn more about these options.
$./configure--enable-optimizations--with-lto
Note
If you are using the Windows Subsystem for Linux (WSL),clone the repository from a native Windows shell programlike PowerShell or thecmd.exe
command prompt,and use a build of Git targeted for Windows,for example, theGit for Windows download from the official Git website.Otherwise, Visual Studio will not be able to find all the project’s filesand will fail the build.
For a concise step by step summary of building Python on Windows,you can readVictor Stinner’s guide.
All supported versions of Python can be builtusing Microsoft Visual Studio 2017 or later.You can download and use any of the free or paid versions ofVisual Studio.
When installing it, select thePython development workloadand the optionalPython native development tools componentto obtain all of the necessary build tools.You can find Git for Windows on theIndividual components tabif you don’t already have it installed.
Note
If you want to build MSI installers, be aware that the build toolchainfor them has a dependency on the Microsoft .NET Framework Version 3.5(which may not be included on recent versions of Windows, such as Windows 10).If you are building on a recent Windows version, use the Control Panel(Programs ‣ Programs and Features ‣ Turn Windows Features on or off)and ensure that the entry.NET Framework 3.5 (includes .NET 2.0 and 3.0) is enabled.
Your first build should use the command line to ensure any external dependenciesare downloaded:
PCbuild\build.bat -c Debug
The above command line build uses the-cDebug
argumentto build in theDebug
configuration,which enables checks and assertions helpful for developing Python.By default, it builds in theRelease
configurationand for the 64-bitx64
platform rather than 32-bitWin32
;use-c
and-p
to control build config and platform, respectively.
After this build succeeds, you can open thePCbuild\pcbuild.sln
solutionin the Visual Studio IDE to continue development, if you prefer.When building in Visual Studio,make sure to select build settings that match what you used with the script(theDebug configuration and thex64 platform)from the dropdown menus in the toolbar.
Note
If you need to change the build configuration or platform,build once with thebuild.bat
script set to those options firstbefore building with them in VS to ensure all files are rebuilt properly,or you may encounter errors when loading modules that were not rebuilt.
Avoid selecting thePGInstrument
andPGUpdate
configurations,as these are intended for PGO builds and not for normal development.
You can run the build of Python you’ve compiled with:
PCbuild\amd64\python_d.exe
See thePCBuild readme for more details on what other software is necessaryand how to build.
WASI is a system interface standard forWebAssembly. Through a combination ofC compilers that can target WebAssembly andwasi-libc providingPOSIX-compatible shims for WASI, it’s possible for CPython to run on a WASIhost/runtime as aguest.
Note
The instructions below assume a Unix-based OS due to cross-compilation forCPython being designed for./configure
/make
.
To build for WASI, you will need to cross-compile CPython. This requires a Ccompiler just like building forUnix as well as:
A C compiler that can target WebAssembly (for example,WASI SDK)
A WASI host/runtime (for example,Wasmtime)
All of this is provided in thedevcontainer. You canalso use what’s installed in the container as a reference of what versions ofthese tools are known to work.
Note
CPython has only been verified with the above tools for WASI. Usingother compilers, hosts, or WASI versionsshould work, but the above toolsand their versions specified in the container are tested via abuildbot.
Building for WASI requires doing a cross-build where you have abuild Pythonto help produce a WASI build of CPython (technically it’s a “host x host”cross-build because the build Python is also the target Python while the hostbuild is the WASI build). This means you effectively build CPython twice: onceto have a version of Python for the build system to use and another that’s thebuild you ultimately care about (that is, the build Python is not meant for use byyou directly, only the build system).
The easiest way to get a debug build of CPython for WASI is to use theTools/wasm/wasi.pybuild
command (which should be run w/ a recent version ofPython you have installed on your machine):
$python3Tools/wasm/wasibuild--quiet----config-cache--with-pydebug
For Python 3.14 and earlier, useTools/wasm/wasi.py
instead.
That single command will configure and build both the build Python and theWASI build incross-build/build
andcross-build/wasm32-wasi
,respectively.
You can also do each configuration and build step separately; the command aboveis a convenience wrapper around the following commands:
$pythonTools/wasm/wasiconfigure-build-python--quiet----config-cache--with-pydebug$pythonTools/wasm/wasimake-build-python--quiet$pythonTools/wasm/wasiconfigure-host--quiet----config-cache$pythonTools/wasm/wasimake-host--quiet
Note
Theconfigure-host
command infers the use of--with-pydebug
from thebuild Python.
Running the separate commands afterwasi.pybuild
is useful if you, for example, only want torun themake-host
step after making code changes.
Once everything is complete, there will be across-build/wasm32-wasi/python.sh
helper file which you can use to run thepython.wasm
file (see the output from theconfigure-host
subcommand):
$cross-build/wasm32-wasi/python.sh--version
You can also useMakefile
targets and they will work as expected thanks totheHOSTRUNNER
environment variable having been set to a similar value asused inpython.sh
:
$make-Ccross-build/wasm32-wasitest
Note
WASI uses acapability-based security model. This means that the WASI hostdoes not give full access to your machine unless you tell it to. Thisalso means things like files can end up being mapped to a different pathinside the WASI host. So, if you try passing a file path topython.wasm
/python.sh
, it needs to match the pathinside theWASI host, not the path on your machine (much like using a container).
Emscripten is a complete open-source compiler toolchain. It compiles C/C++ codeintoWebAssembly/JavaScript executables, for use in JavaScript runtimes,including browsers and Node.js.
Note
The instructions below assume a Unix-based OS due to cross-compilation forCPython being designed for./configure
/make
.
To build for Emscripten, you will need to cross-compile CPython. This requires aC compiler just like building forUnix as well as:
The Emscripten compiler
Node.js
The simplest way to install the Emscripten compiler is:
# Install Emscriptengitclonehttps://github.com/emscripten-core/emsdk./emsdk/emsdkinstall4.0.5./emsdk/emsdkactivate4.0.5source./emsdk/emsdk_env.sh
Updating the Emscripten compiler version often causes breakages. For the bestcompatibility, use the Emscripten version suggested in the cpython repository inTools/wasm/README.md
.
Building for Emscripten requires doing a cross-build where you have abuildPython to help produce an Emscripten build of CPython. This means you buildCPython twice: once to have a version of Python for the build system to use andanother that’s the build you ultimately care about (that is, the build Python isnot meant for use by you directly, only the build system).
The easiest way to get a debug build of CPython for Emscripten is to use theTools/wasm/emscriptenbuild
command (which should be run with a recentversion of Python you have installed on your machine):
python3Tools/wasm/emscriptenbuild--quiet----config-cache--with-pydebug
That single command will configure and build both the build Python and theEmscripten build incross-build/build
andcross-build/wasm32-emscripten/build/python/
, respectively.
You can also do each configuration and build step separately; the command aboveis a convenience wrapper around the following commands:
pythonTools/wasm/emscriptenconfigure-build-python--quiet----config-cache--with-pydebugpythonTools/wasm/emscriptenmake-build-python--quietpythonTools/wasm/emscriptenmake-libffi--quietpythonTools/wasm/emscriptenconfigure-host--quiet----config-cachepythonTools/wasm/emscriptenmake-host--quiet
Note
Theconfigure-host
command infers the use of--with-pydebug
from thebuild Python.
Running the separate commands afteremscriptenbuild
is useful if you, forexample, only want to run themake-host
step after making code changes.
Once everything is complete, there will be across-build/wasm32-emscripten/build/python/python.sh
helper file which youcan use to run thepython.mjs
file:
cross-build/wasm32-emscripten/build/python/python.sh--version
You can also useMakefile
targets and they will work as expected thanks totheHOSTRUNNER
environment variable having been set to a similar value asused inpython.sh
:
make-Ccross-build/wasm32-emscripten/build/python/test
Build and test instructions for Android are maintained in the CPython repositoryatAndroid/README.md.
Compiling Python for iOS requires a macOS machine, on a recent version of macOS,running a recent version of Xcode. Apple expects developers to keep theiroperating systems and tools up-to-date; if your macOS version is more than onemajor release out of date, or your Xcode version is more than a couple of minorversions out of date, you’ll likely encounter difficulties. It is not possibleto compile for iOS using Windows or Linux as a build machine.
A complete build for Python on iOS requires compiling CPython four times: once formacOS; then once for each of the three underlying platforms used by iOS:
An ARM64 device (an iPhone or iPad);
An ARM64 simulator running on a recent macOS machine; and
An x86_64 simulator running on older macOS machine.
The macOS build is required because building Python involves running some Pythoncode. On a normal desktop build of Python, you can compile a Python interpreterand then use that interpreter to run Python code. However, the binaries producedfor iOS won’t run on macOS, so you need to provide an external Pythoninterpreter. From the root of a CPython code checkout, run the following:
$./configure--prefix=$(pwd)/cross-build/macOS$make-j4all$makeinstall
This will build and install Python for macOS into thecross-build/macOS
directory.
The CPython build system can compile a single platform at a time. It is possibletotest a single platform at a time; however, for distribution purposes, youmust compile all three, and merge the results. See theiOS READMEfor details on this merging process.
The following instructions will build CPython for iOS with all extensionsenabled, provided you have installed the build dependencies XZ, BZip2, OpenSSLand libFFI in subfolders of thecross-build
folder. Seethe iOSsection on installing build dependencies for details onhow to obtain these dependencies. These dependencies are all strictly optional,however, including libFFI ishighly recommended, as it is required by thectypes
module which is used on iOS to support accessing native system APIs.
$exportPATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"$./configure\LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/xz/include"\LIBLZMA_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/xz/lib -llzma"\BZIP2_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/bzip2/include"\BZIP2_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/bzip2/lib -lbz2"\LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/libffi/include"\LIBFFI_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/libffi/lib -lffi"\--with-openssl="$(pwd)/cross-build/iphoneos.arm64/openssl"\--host=arm64-apple-ios12.0\--build=arm64-apple-darwin\--with-build-python=$(pwd)/cross-build/macOS/bin/python3.13\--enable-framework$make-j4all$makeinstall
$exportPATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"$./configure\LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/xz/include"\LIBLZMA_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/xz/lib -llzma"\BZIP2_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/bzip2/include"\BZIP2_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/bzip2/lib -lbz2"\LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/libffi/include"\LIBFFI_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/libffi/lib -lffi"\--with-openssl="$(pwd)/cross-build/iphonesimulator.arm64/openssl"\--host=arm64-apple-ios12.0-simulator\--build=arm64-apple-darwin\--with-build-python=$(pwd)/cross-build/macOS/bin/python3.13\--enable-framework$make-j4all$makeinstall
$exportPATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"$./configure\LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/xz/include"\LIBLZMA_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/xz/lib -llzma"\BZIP2_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/bzip2/include"\BZIP2_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/bzip2/lib -lbz2"\LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/libffi/include"\LIBFFI_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/libffi/lib -lffi"\--with-openssl="$(pwd)/cross-build/iphonesimulator.x86_64/openssl"\--host=x86_64-apple-ios12.0-simulator\--build=arm64-apple-darwin\--with-build-python=$(pwd)/cross-build/macOS/bin/python3.13\--enable-framework$make-j4all$makeinstall
These instructions modify yourPATH
before the build. As iOS and macOS sharea hardware architecture (ARM64), it is easy for a macOS ARM64 binary to beaccidentally linked into your iOS build. This is especially common when Homebrewis present on the build system. The most reliable way to avoid this problem isto remove any potential source of other libraries from yourPATH
.
However, thePATH
is not completely bare — it includes theiOS/Resources/bin
folder. This folder contains a collection of scripts thatwrap the invocation of the Xcodexcrun tool, removing user- andversion-specific paths from the values encoded in thesysconfig
module. Copies of these scripts are included in the final build products.
Once this build completes, theiOS/Frameworks
folder will contain aPython.framework
that can be used for testing.
To run the test suite on iOS, complete a build for asimulator platform,ensure the path modifications from the build are still in effect, and run:
$maketestios
The full test suite takes approximately 12 minutes to run on a 2022 M1 MacBookPro, plus a couple of extra minutes to build the testbed application and bootthe simulator. There will be an initial burst of console output while the Xcodetest project is compiled; however, while the test suite is running, there is noconsole output or progress. This is a side effect of how Xcode operates whenexecuted at the command line. You should see an iOS simulator appear during thetesting process; the simulator will booth to an iOS landing screen, the testbedapp will be installed, and then started. The screen of the simulator will beblack while the test suite is running. When the test suite completes, success orfailure will be reported at the command line. In the case of failure, you willsee the full log of CPython test suite output.
You can also run the test suite in Xcode itself. This is required if you want torun on a physical device; it is also the easiest approach if you need to run asingle test, or a subset of tests. See theiOS READMEfor details.
This section explains how to install libraries which are needed to compilesome of CPython’s modules (for example,zlib
).
For Unix-based systems, we try to use system libraries whenever available.This means optional components will only build if the relevant system headersare available. The best way to obtain the appropriate headers will vary bydistribution, but the appropriate commands for some popular distributionsare below.
OnFedora,RHEL,CentOS and otherdnf
-based systems:
$sudodnfinstallgitpkg-config$sudodnfinstalldnf-plugins-core# install this to use 'dnf builddep'$sudodnfbuilddeppython3
Some optional development dependencies are not included in the above.To install some additional dependencies for optional build and test components:
$sudodnfinstall\gccgcc-c++gdblzmaglibc-devellibstdc++-developenssl-devel\readline-develzlib-devellibzstd-devellibffi-develbzip2-devel\xz-develsqlitesqlite-develsqlite-libslibuuid-develgdbm-libs\perfexpatexpat-develmpdecimalpython3-pip
OnDebian,Ubuntu, and otherapt
-based systems, try to get thedependencies for the Python you’re working on by using theapt
command.
First, make sure you have enabled the source packages in the sources list.You can do this by adding the location of the source packages, includingURL, distribution name and component name, to/etc/apt/sources.list
.Take Ubuntu 22.04 LTS (Jammy Jellyfish) for example:
$deb-srchttp://archive.ubuntu.com/ubuntu/jammymain
Alternatively, uncomment lines withdeb-src
using an editor, forexample:
$sudonano/etc/apt/sources.list
For other distributions, like Debian, change the URL and names to correspondwith the specific distribution.
Then you should update the packages index:
$sudoapt-getupdate
Now you can install the build dependencies viaapt
:
$sudoapt-getbuild-deppython3$sudoapt-getinstallpkg-config
If you want to build all optional modules, install the following packages andtheir dependencies:
$sudoapt-getinstallbuild-essentialgdblcovpkg-config\libbz2-devlibffi-devlibgdbm-devlibgdbm-compat-devliblzma-dev\libncurses5-devlibreadline6-devlibsqlite3-devlibssl-dev\lzmalzma-devtk-devuuid-devzlib1g-devlibmpdec-devlibzstd-dev
Note that Debian 12 and Ubuntu 24.04 do not have thelibmpdec-dev
package. You can safelyremove it from the install list above and the Python build will use a bundled version.
FormacOS systems (versions 10.9+),the Developer Tools can be downloaded and installed automatically;you do not need to download the complete Xcode application.
If necessary, run the following:
$xcode-select--install
This will also ensure that the system header files are installed into/usr/include
.
Also note that macOS does not include several libraries used by the Pythonstandard library, includinglibzma
, so expect to see some extension modulebuild failures unless you install local copies of them. As of OS X 10.11,Apple no longer provides header files for the deprecated system version ofOpenSSL which means that you will not be able to build the_ssl
extension.One solution is to install these libraries from a third-party packagemanager, likeHomebrew orMacPorts, and then add the appropriate pathsfor the header and library files to yourconfigure
command.
ForHomebrew, install dependencies usingbrew
:
$brewinstallpkg-configopenssl@3xzgdbmtcl-tkmpdecimalzstd
For Python 3.13 and newer:
$GDBM_CFLAGS="-I$(brew--prefixgdbm)/include"\GDBM_LIBS="-L$(brew--prefixgdbm)/lib -lgdbm"\./configure--with-pydebug\--with-system-libmpdec\--with-openssl="$(brew--prefixopenssl@3)"
For Python 3.11 and 3.12:
$GDBM_CFLAGS="-I$(brew--prefixgdbm)/include"\GDBM_LIBS="-L$(brew--prefixgdbm)/lib -lgdbm"\./configure--with-pydebug\--with-openssl="$(brew--prefixopenssl@3)"
For Python 3.9 and 3.10:
$CPPFLAGS="-I$(brew--prefixgdbm)/include -I$(brew--prefixxz)/include"\LDFLAGS="-L$(brew--prefixgdbm)/lib -L$(brew--prefixxz)/lib"\./configure--with-pydebug\--with-openssl="$(brew--prefixopenssl@3)"\--with-tcltk-libs="$(pkg-config--libstcltk)"\--with-tcltk-includes="$(pkg-config--cflagstcltk)"\--with-dbmliborder=gdbm:ndbm
(--with-dbmliborder
is a workaround for a Homebrew-specific changetogdbm
; see#89452for details.)
ForMacPorts, install dependencies usingport
:
$sudoportinstallpkgconfigopensslxzgdbmtk+quartzmpdecimalzstd
For Python 3.13 and newer:
$GDBM_CFLAGS="-I$(dirname$(dirname$(whichport)))/include"\GDBM_LIBS="-L$(dirname$(dirname$(whichport)))/lib -lgdbm"\./configure--with-pydebug\--with-system-libmpdec
For Python 3.11 and 3.12:
$GDBM_CFLAGS="-I$(dirname$(dirname$(whichport)))/include"\GDBM_LIBS="-L$(dirname$(dirname$(whichport)))/lib -lgdbm"\./configure--with-pydebug
And finally, runmake
:
$make-s-j8
There will sometimes be optional modules added for a new release whichwon’t yet be identified in the OS-level build dependencies. In those cases,just ask for assistance in theCore Development category onDiscourse.
Explaining how to build optional dependencies on a Unix-based system withoutroot access is beyond the scope of this guide.
For more details on various options and considerations for building, referto themacOS README.
Note
While you need a C compiler to build CPython, you don’t need anyknowledge of the C language to contribute! Vast areas of CPython arewritten completely in Python: as of this writing, CPython contains slightlymore Python code than C.
On Windows, extensions are already included and built automatically.
The BeeWare project maintainsscripts for building Android dependencies,and distributespre-compiled binaries for each of them.These binaries are automatically downloaded and used by the CPythonbuild script atAndroid/android.py.
As with CPython itself, the dependencies for CPython must be compiled foreach of the hardware architectures that iOS supports. Consult thedocumentation forXZ,bzip2,OpenSSL andlibffi for details on how to configurethe project for cross-platform iOS builds.
Alternatively, theBeeWare Project maintains aproject for building iOS dependencies, and distributespre-compiled binaries for eachof the dependencies. If you use this project to build the dependenciesyourself, the subfolders of theinstall
folder can be used to configureCPython. If you use the pre-compiled binaries, you should unpack each tarballinto a separate folder, and use that folder as the configuration target.
configure
¶If a change is made to Python which relies on some POSIX system-specificfunctionality (such as using a new system call), it is necessary to update theconfigure script to test for availability of the functionality.Python’sconfigure
script is generated fromconfigure.acusingGNU Autoconf.
After editingconfigure.ac
, runmakeregen-configure
to generateconfigure
,pyconfig.h.in, andaclocal.m4.When submitting a pull request with changes made toconfigure.ac
,make sure you also commit the changes in the generated files.
Python’sconfigure.ac
script requires a specific version ofGNU Autoconf.For Python 3.12 and newer, GNU Autoconf v2.71 is required.For Python 3.11 and earlier, GNU Autoconf v2.69 is required.
The recommended and by far the easiest way to regenerateconfigure
is:
$makeregen-configure
This will use Podman or Docker to do the regeneration with the proper versionof GNU Autoconf.
If you cannot (or don’t want to) usemakeregen-configure
,install theautoconf-archive andpkg-config utilities,and make sure thepkg.m4
macro file located in the appropriateaclocal location:
$ls$(aclocal--print-ac-dir)|greppkg.m4
Note
Runningautoreconf is not the same as runningautoconf.For example, runningautoconf by itself will not regeneratepyconfig.h.in
.autoreconf runsautoconf and a number of other toolsrepeatedly as appropriate.
Maintenance branches (notmain
) have a special file located inDoc/data/pythonX.Y.abi
that allows us to know if a given pull requestaffects the public ABI. This file is used by the GitHub CI in a checkcalledCheckiftheABIhaschanged
that will fail if a given pull requesthas changes to the ABI and the ABI file is not updated.
This check acts as a fail-safe anddoesn’t necessarily mean that the pullrequest cannot be merged. When this check fails you should add the relevantrelease manager to the PR so that they are aware of the change and they canvalidate if the change can be made or not.
Important
ABI changes are allowed before the first release candidate. After the first releasecandidate, all further releases must have the same ABI for ensuring compatibilitywith native extensions and other tools that interact with the Python interpreter.See the documentation about therelease candidate phase.
When the PR check fails, the associated run will have the updated ABI fileattached as an artifact. After release manager approval, you can download andadd this file into your PR to pass the check.
You can regenerate the ABI file by yourself by invoking theregenabidump
Make target. Note that for doing this you need to regenerate the ABI file inthe same environment that the GitHub CI uses to check for it. This is becausedifferent platforms may include some platform-specific details that make thecheck fail even if the Python ABI is the same. The easier way to regeneratethe ABI file using the same platform as the CI uses is by using Docker:
#IntheCPythonroot:$dockerrun-v$(pwd):/src:Z-w/src--rm-itubuntu:22.04\bash/src/.github/workflows/regen-abidump.sh
Note that theubuntu
version used to execute the script matters andmust match the version used by the CI to check the ABI. See the.github/workflows/build.yml
file for more information.
This section lists some of the common problems that may arise during thecompilation of Python, with proposed solutions.
Under some circumstances you may encounter Python errors in scripts likeParser/asdl_c.py
orPython/makeopcodetargets.py
while runningmake
.Python auto-generates some of its own code, and a full build from scratch needsto run the auto-generation scripts. However, this makes the Python build requirean already installed Python interpreter; this can also cause version mismatcheswhen trying to build an old (2.x) Python with a new (3.x) Python installed, orvice versa.
To overcome this problem, auto-generated files are also checked into theGit repository. So if you don’t touch the auto-generation scripts, there’sno real need to auto-generate anything.
Python is used widely enough that practically all code editors have some formof support for writing Python code. Various coding tools also include Pythonsupport.
For editors and tools which the core developers have felt some special commentis needed for codingin Python, seeAdditional resources.
There are several top-level directories in the CPython source tree. Knowing whateach one is meant to hold will help you find where a certain piece offunctionality is implemented. Do realize, though, there are always exceptions toevery rule.
Doc
The official documentation. This is whathttps://docs.python.org/ uses.See alsoBuilding the documentation.
Grammar
Contains theEBNF grammar file forPython.
Include
Contains all interpreter-wide header files.
Lib
The part of the standard library implemented in pure Python.
Mac
Mac-specific code (for example, using IDLE as a macOS application).
Misc
Things that do not belong elsewhere. Typically this is varying kinds ofdeveloper-specific documentation.
Modules
The part of the standard library (plus some other code) that is implementedin C.
Objects
Code for all built-in types.
PC
Windows-specific code.
PCbuild
Build files for the version of MSVC currently used for the Windowsinstallers provided on python.org.
Parser
Code related to the parser. The definition of the AST nodes is also kepthere.
Programs
Source code for C executables, including the main function for theCPython interpreter.
Python
The code that makes up the core CPython runtime. This includes thecompiler, eval loop and various built-in modules.
Tools
Various tools that are (or have been) used to maintain Python.
If you’d like to start contributing to CPython without needing to set up a localdeveloper environment, you can useGitHub Codespaces.Codespaces is a cloud-based development environment offered by GitHub thatallows developers to write, build, test, and debug code directly within theirweb browser or in Visual Studio Code (VS Code).
To help you get started, CPython contains adevcontainer folderwith a JSON configuration file that provides consistent and versioned codespaceconfigurations for all users of the project. It also contains a Dockerfile thatallows you to set up the same environment but locally in a Docker container ifyou’d prefer to use that directly.
Here are the basic steps needed to contribute a pull request using Codespaces.You first need to navigate to theCPython repo hosted on GitHub.
Then you will need to:
Press the,
key to launch the codespace setup screen for the currentbranch (alternatively, click the greenCode button and choosethecodespaces
tab and then press thegreenCreate codespace on main button).
A screen should appear that lets you know your codespace is being set up.(Note: Since the CPython devcontainer is provided, codespaces will use theconfiguration it specifies.)
Aweb version of VS Code will open inside your webbrowser, already linked up with your code and a terminal to the remotecodespace where CPython and its documentation have already been built.
Use the terminal with the usual Git commands to create a new branch, commitand push your changes once you’re ready!
If you close your repository and come back later you can always resume yourcodespace by navigating to the CPython repo, selecting the codespaces tab andselecting your most recent codespaces session. You should then be able to pickup from where you left off!
On the bottom left side of the codespace screen you will see a green or greysquare that saysCodespaces. You can click this for additionaloptions. If you prefer working in a locally installed copy of VS Code you canselect the optionOpeninVSCode
. You will still be working on the remotecodespace instance, thus using the remote instance’s compute power. The computepower may be a much higher spec than your local machine which can be helpful.
If you want more control over the environment, or to work offline,you can use the same container used inGitHub Codespaces directly.This is meant for users who have (or want to get) some experiencewith containers.These instructions assume a Unix-like environment withDocker orPodmaninstalled.
Dev container imagesare available from theGitHub Container Registry (GHCR) account for the Python org.
To run the container and launch a Bash shell, run one of the following commandsin a clone of the CPython repository.
dockerrun-it--rm--volume$PWD:/workspace--workdir/workspaceghcr.io/python/devcontainer:latest
podmanrun-it--rm--volume$PWD:/workspace:Z--workdir/workspaceghcr.io/python/devcontainer:latest
Note that the container has read/write access to the working directory.You may want to use a separate clone of CPython, or runmakeclean
to remove caches and build output generated for your host OS.
If you prefer, you can build the container image yourself. In a clone of thecpython-devcontainers repo,build the container and name itcpython-dev
:
dockerbuilddevcontainer/--tagcpython-dev
(Substitutepodman
fordocker
if you use Podman.)
The same command will update any existingcpython-dev
container.Run it again from time to time – especially if the container stopsworking for you.
To run the container and launch a Bash shell, run one of the following commandsin a clone of the CPython repository.
dockerrun-it--rm--volume$PWD:/workspace--workdir/workspacecpython-dev
podmanrun-it--rm--volume$PWD:/workspace:Z--workdir/workspacecpython-dev
The same caveats outlined above when running from a container image from GHCRalso apply here.