2012-04-30 12 views
15

Questo è più di un fenomeno "interessante" che ho incontrato in un modulo Python che sto cercando di capire, piuttosto che una richiesta di aiuto (anche se una soluzione sarebbe anche utile).Immutabilità di stringa in CPython violata

>>> import fuzzy 
>>> s = fuzzy.Soundex(4) 
>>> a = "apple" 
>>> b = a 
>>> sdx_a = s(a) 
>>> sdx_a 
'A140' 
>>> a 
'APPLE' 
>>> b 
'APPLE' 

Sì, così il modulo fuzzy viola totalmente l'immutabilità delle stringhe in Python. È in grado di farlo perché è un'estensione C? E questo costituisce un errore in CPython così come il modulo, o anche un rischio per la sicurezza?

Inoltre, qualcuno può pensare a un modo per aggirare questo comportamento? Mi piacerebbe essere in grado di mantenere l'iniziale maiuscola della stringa.

Cheers,

Alex

+0

Non vedo da nessuna parte nel C generato dove si muta la stringa. –

+0

@ IgnacioVazquez-Abrams: forse mi manca qualcosa, ma non lo muta in '__call__' [' __pyx_f_5fuzzy_7Soundex ___ call__']? Dichiara un cdef char ptr che viene impostato uguale al risultato di una chiamata PyString_AsString e quindi modifica il contenuto. – DSM

+0

@DSM: non nel codice in Bitbucket. Vedo solo letture da esso, su [riga 891] (https://bitbucket.org/yougov/fuzzy/src/c210ad2f3f68/src/fuzzy.c#cl-891). –

risposta

13

Questo errore è stato risolto back in February; aggiorna la tua versione.

Per rispondere alla tua domanda, sì, ci sono diversi modi per modificare i tipi immutabili al livello C. Le implicazioni sulla sicurezza sono sconosciute, e forse anche inconoscibili, a questo punto.

+0

Grazie per questa risposta! In realtà, ho usato easy_install per installare fuzzy solo tre settimane fa. La versione che mi sta dando è fuzzy-1.0-py2.7-win-amd64.egg, ed è questa versione che ha l'errore. – Alex

+0

@Alex: Non lo tengono sempre aggiornato lì; installa da Bitbucket. –

2

non ho il modulo fuzzy a disposizione per testare in questo momento, ma quanto segue crea una stringa con una nuova identità:

>>> a = "hello" 
>>> b = ''.join(a) 
>>> b 
'hello' 
>>> id(a), id(b) 
(182894286096, 182894559280) 
+0

Sì, questo funziona :) – Alex

0

se cambia la stringa immutabile, è un bug, puoi aggirare questo:

s(a.upper()) 
2

Non so molto su CPython, ma sembra in fuzzy.c dichiara char *cs = s, dove s è l'input per __call__. Muta quindi cs[i], che ovviamente muta s[i] e quindi la stringa originale. Questo è sicuramente un bug con Fuzzy e dovresti archiviarlo sullo bitbucket. Come ha detto la risposta di Greg, usando ''.join(a) creerà una nuova copia.

+0

È stato archiviato su Bitbucket. Due volte. –

Problemi correlati