2013-05-02 19 views
5

Sto compilando diverse versioni di Python per il mio sistema e mi piacerebbe sapere dove è definito il banner di avvio nella sorgente in modo da poterlo modificare per ogni versione. Ad esempio, quando l'interprete si avvia visualizzaDove è definito il banner di avvio Python?

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. 
>>> 

mi piacerebbe modificare la stringa default ad altre cose per segnalare che la versione che sto utilizzando, ma io sono interessato a come tutta la baracca è montato anche . Dove è definito?

+0

Probabilmente si potrebbe ack per '__DATE__' o' __TIME__' per ottenere il codice relativo. –

+0

Puoi usare questo codice per cambiare ciò che mostra l'interprete - python -ic 'import sys; sys.ps1 = "$"; sys.ps2 = "" ' – fixxxer

risposta

14

Usiamo grep per entrare nell'arena. Non ho intenzione di preoccuparmi di cercare default perché otterrò troppi risultati, ma proverò Type "Help", che non dovrebbe apparire troppe volte. Se è una stringa C, le virgolette saranno sfuggite. Dovremmo cercare le stringhe C prima e le stringhe Python in seguito.

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

E 'in Modules/main.c, in Py_Main(). Più scavo ci dà questa linea:

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

Perché "on" è nella stringa di formato, Py_GetPlatform() deve essere linux e Py_GetVersion() deve dare la stringa che vogliamo ...

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

Questo sembra essere molto promettente. ..

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

Dobbiamo volere Py_GetBuildInfo(), perché è all'interno delle parentesi ...

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

Questo sembra un po 'troppo ovvio.

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; 
} 

Quindi, default è il nome del ramo Mercurial. Esaminando i makefile, possiamo capire che questo proviene dalla macro HGTAG. Una variabile makefile denominata HGTAG produce la variabile e tale variabile viene eseguita come un comando. Così,

Soluzione semplice

Quando si costruisce 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

Vale la pena ricordare che la prima parte dell'output è la stringa di versione di Python restituita da 'Py_GetVersion'. Il contenuto tra parentesi (incluso 'default') fa parte della stringa restituita da' Py_GetBuildInfo', il che mi suggerisce che probabilmente può essere ottimizzato in fase di compilazione. – Blckknght

+0

@Blckknght: È proprio dove sono diretto ... –

+0

Complimenti per aver scritto questo post come un romanzo poliziesco. Per una lettura elettrizzante! – LondonRob

0

Sembra che se si aggiunge un tag Mercurial prima di costruire, quindi default sarà sostituito con il nome del tag (fonte: Modules/getbuildinfo.c :)

Fondamentalmente sembra che scelga il nome default perché questo è il nome del ramo. Sembra che l'interprete sia costruito con il nome del tag, se ne esiste uno, o il nome del ramo se nessun tag (oltre allo tip) esiste sulla copia di lavoro corrente.

Problemi correlati