-1

I was recently looking through the CPython source code and noticed something rather intriguing:

/* Minimal main program -- everything is loaded from the library */

#include "Python.h"
#include "pycore_pylifecycle.h"

#ifdef MS_WINDOWS
int
wmain(int argc, wchar_t **argv)
{
    return Py_Main(argc, argv);
}
#else
int
main(int argc, char **argv)
{
    return _Py_UnixMain(argc, argv);
}
#endif

The main function just calls a different function as is stated in the comment above

Minimal main program

And those two functions which were called (Py_Main and _Py_UnixMain) don't seem to do drastically different or very complex operations either, and they eventually call the same function (pymain_main):

int
Py_Main(int argc, wchar_t **argv)
{
    _PyMain pymain = _PyMain_INIT;
    pymain.use_bytes_argv = 0;
    pymain.argc = argc;
    pymain.wchar_argv = argv;

    return pymain_main(&pymain);
}

int
_Py_UnixMain(int argc, char **argv)
{
    _PyMain pymain = _PyMain_INIT;
    pymain.use_bytes_argv = 1;
    pymain.argc = argc;
    pymain.bytes_argv = argv;

    return pymain_main(&pymain);
}

It appears that those operations could very easily be done in the main or wmain functions.

My question is if there is a clear benefit of this choice from a design and structure point of view? Why did the developers of CPython, probably, decide to effectively create a new main function instead of using the standard one? Does it make maintenance or debugging easier?

Link to the main
Link to Py_Main and _Py_UnixMain

4
  • The #ifdef directive appears to be the motivation. They wanted to distingush between Windows and other operating systems. Commented Nov 22, 2018 at 21:37
  • @RobertHarvey added the called functions to the question as well, they appear to be more alike than they are different, couldn't they just be incorporated into main and wmain? Commented Nov 22, 2018 at 22:03
  • There are still differences. There only has to be one significant difference to justify a different method. Commented Nov 23, 2018 at 3:07
  • @RobertHarvey that's entirely correct, but as the answer denoted "It would not be necessary to offer these functions as their contents could be written in the real main/wmain" Commented Nov 23, 2018 at 19:35

1 Answer 1

5

Python is not just an application, it can also be embedded as a library. A program can only contain one main symbol, so CPython must not provide it if it is intended to be usable as a library.

The use of different Main functions in the Python API is motivated by their different argument types, i.e. wchar vs char. It would not be necessary to offer these functions as their contents could be written in the real main/wmain, but this keeps Python's file with the main() implementation minimal, and thus more maintainable.

+-------------+        +-----------+
| Application |  --->  |  Library  |
|   main()    |        | Py_Main() |
+-------------+        +-----------+
1
  • 1
    An executable can be (but vanishingly rarely is) a shared library. See for example on Windows or on Linux. Commented Nov 23, 2018 at 7:55

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.