`str.translate` caching values causes incorrect result
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 35.9k
- Métriques de merge des PR
- Métriques de PR en attente
Description
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
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par exécuter le reproducteur Python fourni sur les trois cas de tables de traduction avec compteur et comparez le nombre d’appels à getitem ainsi que les résultats. Localisez ensuite le point d’entrée de CPython et les tests pour str.translate ; le travail est terminé lorsque le comportement est cohérent avec le contrat documenté et couvert par des tests de régression.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- backend
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 45/100