O CÓDIGO FONTE DO PYTHON
Muitos desenvolvedores trabalham com uma linguagem por anos sem nunca baixar o código-fonte do interpretador ou compilador, mesmo estando disponível a todos. Podemos tanto acessar o código pelo navegador, ou baixa-lo com alguma ferramenta de versionamento de código como o Git ou então o Mercurial. Também existe a opção de baixar todo o pacote num arquivo compactado no site oficial do repositório onde os códigos estão disponibilizados.
Conheço essa realidade por experiência própria! Raríssimas foram as vezes em que baixei e analisei o código das ferramentas de código aberto que utilizei e, na maioria das vezes em que fiz o downloads do fontes para o disco local, foi porque o tutorial que estava utilizando exigia.
Até pouco tempo o Python utiliza o sistema de gerenciamento de versão Mercurial, porém, em vista de que o git se tornou por livre adoção dos desenvolvedores quase que um padrão, o código de todo o interpretador do Python e suas bibliotecas agora estão no Github e o mesmo se tornou o repositório oficial do projeto.
Antes de acessarmos os repositório, é importante dizer, ou então relembrar, que o interpretador oficial do Python se chama CPython. Não é difícil de perceber que o caractere C a frente do nome Python indica que essa versão do interpretador foi escrita com a linguagem C.
O ENTRY POINT
O Entry Point ou o ponto de entrada de uma aplicação é a nomenclatura utilizada para se referir a primeira função que é invocada na execução de um Script ou de uma aplicação.
O interpretador do Python, por padrão, é escrito em C. No entanto, nem todos os módulos nativos são desenvolvidos somente com a linguagem C e também, até porque, nem todos os módulos contidos numa instalação padrão foram escritos pela equipe de desenvolvedores do Python.
Por exemplo, o SQLite está contido por padrão em todas versões do Python, o mesmo utiliza somente código C, porém, o seu desenvolvimento é feito por outro grupo de desenvolvedores.
O código a seguir é o ponto inicial do interpretador do Python, ou seja, é por essa função que o interpretador inicia a execução.
main(int argc, char **argv)
{
wchar_t **argv_copy;
/* We need a second copy, as Python might modify the first one. */
wchar_t **argv_copy2;
int i, res;
char *oldloc;
/* Force malloc() allocator to bootstrap Python */
#ifdef Py_DEBUG
(void)_PyMem_SetupAllocators("malloc_debug");
# else
(void)_PyMem_SetupAllocators("malloc");
# endif
argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
if (!argv_copy || !argv_copy2) {
fprintf(stderr, "out of memory\n");
return 1;
}
/* 754 requires that FP exceptions run in "no stop" mode by default,
* and until C vendors implement C99's ways to control FP exceptions,
* Python requires non-stop mode. Alas, some platforms enable FP
* exceptions by default. Here we disable them.
*/
#ifdef __FreeBSD__
fedisableexcept(FE_OVERFLOW);
#endif
oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
if (!oldloc) {
fprintf(stderr, "out of memory\n");
return 1;
}
#ifdef __ANDROID__
/* Passing "" to setlocale() on Android requests the C locale rather
* than checking environment variables, so request C.UTF-8 explicitly
*/
setlocale(LC_ALL, "C.UTF-8");
#else
/* Reconfigure the locale to the default for this process */
setlocale(LC_ALL, "");
#endif
if (_Py_LegacyLocaleDetected()) {
_Py_CoerceLegacyLocale();
}
/* Convert from char to wchar_t based on the locale settings */
for (i = 0; i < argc; i++) {
argv_copy[i] = Py_DecodeLocale(argv[i], NULL);
if (!argv_copy[i]) {
PyMem_RawFree(oldloc);
fprintf(stderr, "Fatal Python error: "
"unable to decode the command line argument #%i\n",
i + 1);
return 1;
}
argv_copy2[i] = argv_copy[i];
}
argv_copy2[argc] = argv_copy[argc] = NULL;
setlocale(LC_ALL, oldloc);
PyMem_RawFree(oldloc);
res = Py_Main(argc, argv_copy);
/* Force again malloc() allocator to release memory blocks allocated
before Py_Main() */
#ifdef Py_DEBUG
(void)_PyMem_SetupAllocators("malloc_debug");
# else
(void)_PyMem_SetupAllocators("malloc");
# endif
for (i = 0; i < argc; i++) {
PyMem_RawFree(argv_copy2[i]);
}
PyMem_RawFree(argv_copy);
PyMem_RawFree(argv_copy2);
return res;
}
#endif
Caso queiras ir no repositório onde estão os códigos fontes do Python e analisar todo o módulo, utilize este link que lhe direcionará a função em C que imprimimos acima.
Tags python, c, cpp, python.c, entry point, ponto de entrada
Comentários
comments powered by Disqus