diff --git a/objets.py b/objets.py index 7f7c326..b78da5f 100644 --- a/objets.py +++ b/objets.py @@ -518,14 +518,30 @@ class CransLdapObject(object): # Tests de droits. if not mixed_attrs[0].is_modifiable(self.conn.droits + self.conn._check_parent(self.dn) + self.conn._check_self(self.dn)): raise EnvironmentError("Vous ne pouvez pas toucher aux attributs de type %r." % (attr)) - self._modifs[attr] = attrs_before_verif - for attribut in attrs_before_verif: - if attribut.unique: - try: + + + # On ajoute des locks sur les nouvelles valeurs + locked = [] + try: + for attribut in attrs_before_verif: + if attribut.unique and not attribut in self._modifs.get(attr, []): self.conn.lockholder.addlock(attr, str(attribut), self.lockId) - except: - self._modifs[attr] = list(self.attrs[attr]) - raise + locked.append((attr, str(attribut), self.lockId)) + except ldap_locks.LockError: + # Si on ne parvient pas à prendre le lock pour l'une des valeurs + # on libère les locks pris jusque là et on propage l'erreur + # les anciens locks et self._modifs reste bien inchangés + for (a, b, c) in locked: + self.conn.lockholder.removelock(a, b, c) + raise + + # On retire les locks des attributs que l'on ne va plus utiliser + for attribut in self._modifs.get(attr, []): + if attribut.unique and not attribut in attrs_before_verif: + self.conn.lockholder.removelock(attr, str(attribut), self.lockId) + + # On met à jour self._modifs avec les nouvelles valeurs + self._modifs[attr] = attrs_before_verif def search_historique(self, ign_fields=HIST_IGNORE_FIELDS): u"""Récupère l'historique