patch does not correctly restore state on objects without __dict__
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:
from unittest.mock import patch
class Proxy(object):
config = {}
def __getattr__(self, name):
return self.config[name]
def __setattr__(self, name, value):
if name == 'config':
object.__setattr__(self, name, value)
return
self.config[name] = value
def __delattr__(self, name):
self.config[name] = 'DEFAULT'
p = Proxy()
p.a = True
print(p.a)
with patch('__main__.p.a', False):
print(p.a)
print(p.a)
Expected
True
False
True
Actual
True
False
DEFAULT
Note that this is a relatively niche issue, but for example in a config system (i.e. https://github.com/pytorch/pytorch/pull/140779), if you don't want to have a delete work, (i.e. have it set it back to a default value), the code in https://github.com/python/cpython/blob/94a7a4e22fb8f567090514785c69e65298acca42/Lib/unittest/mock.py#L1637 will call delattr, and then not call setattr, because it still has the attr.
Possible fixes:
If delattr throws (maybe NotImplementederror), call setattr instead (this is nice and explicit + removes the hacky workaround I have to do).
If the value after it's been deleted doesn't equal the original value, reassign it? (this might require objects to be comparable, not sure if that is already an issue here).
Either way I wanted to see if there was any interest in fixing this, and if anyone saw a solution that seemed reasonable enough.
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 la reproduction dans l’issue et examinez la logique de restauration dans Lib/unittest/mock.py autour de la ligne 1637. Comparez la manière dont patch gère les attributs des objets dépourvus de dict lorsque leur suppression modifie la valeur observée. Le travail est terminé lorsque l’exemple restaure p.a à True tout en préservant le comportement existant pour les objets ordinaires, avec l’ajout d’une couverture de régression dans les tests unittest.mock concernés.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- testing-qa
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100