`str.translate` caching values causes incorrect result
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug report
Bug description:
It seems that str.translate is caching values internally and this is causing unintended results.
When the translation table returns an ordinal or a string ordinal string, it caches the values returned by __getitem__ and will not call the function again. However if you are returning a 2-length string this doesn't occur (and in fact calls __getitem__ an additional time for some reason?).
I expect that the __getitem__ be executed for every character since the function documentation does not mention this caching value and more-so the function behaves inconsistently.
This is likely caused by #65317.
class counting_translate_ord(dict[int, int]):
def __init__(self) -> None:
super().__init__()
self.missing_calls = 0
def __getitem__(self, key: int) -> int:
self.missing_calls += 1
return ord(str(self.missing_calls % 10))
table = counting_translate_ord()
print(("----").translate(table)) # 1111
print(table.missing_calls) # 1
print(("!@#$").translate(table)) # 2345
print(table.missing_calls) # 5
class counting_translate_str(dict[int, str]):
def __init__(self) -> None:
super().__init__()
self.missing_calls = 0
def __getitem__(self, key: int) -> str:
self.missing_calls += 1
return str(self.missing_calls % 10)
table = counting_translate_str()
print(("----").translate(table)) # 1111
print(table.missing_calls) # 1
print(("!@#$").translate(table)) # 2345
print(table.missing_calls) # 5
class counting_translate_2str(dict[int, str]):
def __init__(self) -> None:
super().__init__()
self.missing_calls = 0
def __getitem__(self, key: int) -> str:
self.missing_calls += 1
return format(self.missing_calls, "02d")[:2]
table = counting_translate_2str()
print(("----").translate(table)) # 02030405
print(table.missing_calls) # 5
print(("!@#$").translate(table)) # 07080910
print(table.missing_calls) # 10
CPython versions tested on:
3.12
Operating systems tested on:
Linux
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Führen Sie zunächst den bereitgestellten Python-Reproducer für die drei Fälle mit zählenden Übersetzungstabellen aus und vergleichen Sie die Anzahl ihrer getitem-Aufrufe sowie ihre Ergebnisse. Suchen Sie anschließend den CPython-Einstiegspunkt und die Tests für str.translate; abgeschlossen ist die Aufgabe, wenn das Verhalten mit dem dokumentierten Vertrag übereinstimmt und durch Regressionstests abgedeckt ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- backend
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 45/100