In this post, we will take a dissecion of source code of Python.
To benefit the simplicity and meanwhile follow the most recent functionnalities, I choose Python 3.6.9
to do the analysis.
The first step, is to build!
Build Python
As other projects, Python uses autoconf
toolset to configure and then make
to build itself. If it doesn’t make sense to you, just ignore it. What you really need is just a set of single commands to make it:
- Run
./configure
, it will detect your environment along with the architecture, the dependencies, the features supported by your compiler - After that, if there is no error, a
Makefile
file should be generated and placed in the same directory - Run
make
, and you will get your own Python build!
Now we use default configurations to build, because we don’t aim at building a Python binary. If you’d like to play with Python builds, you can find more information at https://docs.python.org/3.6/using/unix.html#building-python.
Project Structure
Before we configure the project, the structure of project is really clear and simple:
1 | aclocal.m4 configure Lib Misc Programs python-config.py |
aclocal.m4
, config.guess
, config.sub
, configure
, configure.ac
, install-sh
, Makefile.pre.in
, pyconfig.h.in
are files which concerns the configuration and the compilation. LICENSE
is the license file.
Doc/
This folder contains the documentation of Python.
Grammar1/
In Grammar folder, there is only one file, which described the abstract grammar representation of Python.
Include/
All Python headers used during Python compilation. Some of those will be intalled in your system for a further development.
Lib/
All libraries written in Python.
Mac/
Build tools for macOS build.
Misc/
Other things, not so important.
Modules/
Modules written in C.
Objects/
Declarations and implementations of various Python Objects.
Parser/
Python code parser.
PC/
The code for Windows PC.
PCbuild/
The Windows PC build files, such as Visual Studio Prject files.
Programms/
Main functions of Python.
Python/
Python main implementation codes.
Tools/
Auxiliary tools and demo.
Programm Entry, Programs/python.c
In the analysis, we start by the main entry of program.
At the beginning, "Python.h"
and <locale.h>
are imported.
Then, the main function has two branches:
Windows
On Windows, the function wmain
instead of main
is used as the main entry.
1 | int |
This function is for the unicode environment, you can go to the doc page of Microsoft for further information:
https://docs.microsoft.com/en-us/cpp/c-language/using-wmain?view=vs-2019.
In the main function, it calls the real Main Function of Python, Py_Main
with command-line arguments.
Other Unix-Like Systems
It’s not so simple as the one for Windows.
1 | wchar_t **argv_copy; |
In this code, some necessary variables are declared, regarding C89 or above. Then, to copy arguments, Python requests to use malloc
to allocate memories by invoking (void)_PyMem_SetupAllocators("malloc");
.
Then two memory spaces are allocated:
1 | argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); |
Then, Python did one thing like this:
1 | oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); |
This line will return C
locale and store it in oldloc
.
Then Python tries to set locale with user-prefered one by setlocale(LC_ALL, "")
, and to decode all command line arguments with new locale.
1 | setlocale(LC_ALL, ""); |
After decoding command line arguments with user-prefered locale, Python would like to use the old default C
locale and do some clean things.
1 | setlocale(LC_ALL, oldloc); |
After everything about decoding and copying arguments is ready, run Python main process:
1 | res = Py_Main(argc, argv_copy); |
After finishing Python main process, all memory spaces which were allocated should be released properly with following code:
1 | /* Force again malloc() allocator to release memory blocks allocated |
And then, return the result through return res;
.
Before the end
In this post, we tried to compile Python with all default configurations, and we explicited the main entry function.
In the next post, we’ll get involve with Py_Main
function, as well as some Python Objects or types if possible.
See you then!