Непрерывность строк в CPython нарушена

Это более интересные явления, которые я встречал в модуле Python, который я пытаюсь понять, а не запрос на помощь (хотя решение также было бы полезно).

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

Да, поэтому модуль fuzzy полностью нарушает неизменность строк в Python. Может ли это сделать, потому что это C-расширение? И это является ошибкой в ​​CPython, а также модулем или даже угрозой безопасности?

Кроме того, может ли кто-нибудь подумать о способе обойти это поведение? Я хотел бы иметь возможность сохранить первоначальную заглавную строку.

Приветствия,

Алекс

Ответы

Ответ 1

Эта ошибка была решена еще в феврале; обновите свою версию.

Чтобы ответить на ваш вопрос, да, существует несколько способов изменения неизменяемых типов на уровне C. Последствия безопасности неизвестны и, возможно, даже непознаваемы, на данный момент.

Ответ 2

У меня нет модуля fuzzy, доступного для тестирования прямо сейчас, но следующее создает строку с новым идентификатором:

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

Ответ 3

Я мало знаю о CPython, но он выглядит как fuzzy.c, он объявляет char *cs = s, где s - это вход в __call__. Затем он мутирует cs[i], который, очевидно, будет мутировать s[i] и, следовательно, исходную строку. Это определенно ошибка с Fuzzy, и вы должны записать ее на bitbucket. Как сказал Грег, использование ''.join(a) создаст новую копию.

Ответ 4

Если он изменяет неизменяемую строку, это ошибка, вы можете обойти это:

s(a.upper())