2013-05-02 13 views
5

Kompiluję kilka różnych wersji Pythona dla mojego systemu i chciałbym wiedzieć, gdzie w źródle zdefiniowany jest banner startowy, więc mogę go zmienić dla każdej wersji. Na przykład, gdy rozpoczyna interpreter wyświetlaGdzie jest zdefiniowany banner uruchamiania Pythona?

Python 3.3.1 (default, Apr 28 2013, 10:19:42) 
[GCC 4.7.2 20121109 (Red Hat 4.7.2-8)] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 

Chciałbym zmienić ciąg default do innych rzeczy, aby zasygnalizować, która wersja używam, ale jestem również zainteresowany tym, jak cała shebang jest zmontowane . Gdzie to jest zdefiniowane?

+0

Możesz prawdopodobnie uzyskać słowo "__DATE__" lub "__TIME__", aby uzyskać odpowiedni kod. –

+0

Możesz użyć tego kodu, aby zmienić to, co pokazuje interpreter - python -ic 'import sys; sys.ps1 = "$"; sys.ps2 = "" " – fixxxer

Odpowiedz

14

Użyjmy grep, aby dostać się na pole do gry. Nie będę zawracać sobie głowy szukaniem default, ponieważ dostanę zbyt wiele wyników, ale spróbuję Type "Help", która nie powinna pojawiać się zbyt wiele razy. Jeśli jest to ciąg znaków C, cytaty zostaną usunięte. Powinniśmy najpierw szukać łańcuchów C i łańcuchów Pythona.

Python $ grep 'Type \\"help\\"' . -Ir 
./Modules/main.c: "Type \"help\", \"copyright\", \"credits\" or \"license\" " \ 

Jest w Modules/main.c w Py_Main(). Więcej kopania daje nam ten wiersz:

fprintf(stderr, "Python %s on %s\n", 
    Py_GetVersion(), Py_GetPlatform()); 

Bo „on” jest w ciągu formatu, Py_GetPlatform() musi być linux i Py_GetVersion() musi dać ciąg chcemy ...

Python $ grep Py_GetVersion . -Irl 
... 
./Python/getversion.c 
... 

To wygląda obiecująco. ..

PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s", 
       PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler()); 

musi Chcemy Py_GetBuildInfo(), bo to w nawiasach ...

Python $ grep Py_GetBuildInfo . -Irl 
... 
./Modules/getbuildinfo.c 
... 

To wygląda na zbyt oczywiste.

const char * 
Py_GetBuildInfo(void) 
{ 
    static char buildinfo[50 + sizeof(HGVERSION) + 
          ((sizeof(HGTAG) > sizeof(HGBRANCH)) ? 
          sizeof(HGTAG) : sizeof(HGBRANCH))]; 
    const char *revision = _Py_hgversion(); 
    const char *sep = *revision ? ":" : ""; 
    const char *hgid = _Py_hgidentifier(); 
    if (!(*hgid)) 
     hgid = "default"; 
    PyOS_snprintf(buildinfo, sizeof(buildinfo), 
        "%s%s%s, %.20s, %.9s", hgid, sep, revision, 
        DATE, TIME); 
    return buildinfo; 
} 

Tak, default to nazwa oddziału Mercurial. Sprawdzając pliki makefile, możemy stwierdzić, że pochodzi on z makro HGTAG. Zmienna pliku Makefile o nazwie HGTAG tworzy zmienną, która jest uruchamiana jako polecenie. Więc

Proste rozwiązanie

Przy budowie Python,

Python $ ./configure 
Python $ make HGTAG='echo awesome' 
Python $ ./python 
Python 3.2.3 (awesome, May 1 2013, 21:33:27) 
[GCC 4.7.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 
+0

Warto wspomnieć, że pierwszą częścią wyjścia jest ciąg wersji Pythona, zwrócony przez' Py_GetVersion'. Rzeczy w nawiasach (w tym 'default') są częścią ciągu zwracanego przez' Py_GetBuildInfo', co sugeruje mi, że prawdopodobnie zostanie zmodyfikowany podczas kompilacji. – Blckknght

+0

@Blckknght: Dokładnie tam, dokąd zmierzam ... –

+0

Dobra robota za napisanie tego posta jak kryminał. Sprawia, że ​​czytanie jest ekscytujące! – LondonRob

0

Wygląda na to, jeśli dodać tag rtęciowego przed budować, a następnie default zostanie zastąpiony nazwą tagu (źródło: Modules/getbuildinfo.c : _Py_hgidentifier())

Zasadniczo wydaje się, że wybiera nazwę default, ponieważ jest to nazwa oddziału. Wygląda na to, że interpreter jest zbudowany z nazwą znacznika, jeśli istnieje, lub nazwą oddziału, jeśli nie ma znacznika (oprócz tip) na bieżącej kopii roboczej.

Powiązane problemy