Python 3 | Exception-Klasse vom String "erhalten"

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
rotten_corpse
User
Beiträge: 3
Registriert: Freitag 13. Dezember 2013, 22:31

Ich schreib gerade an einem kleinen Objekt-Netzwerk-Proxy-Modul, da hab ich folgendes Problem.

Auf der Serverseite wird durch Ausführen einer Methode eines Objekts eine Exception geworfen:

Code: Alles auswählen

                   try:
                        msg.ProxyValueResponse(getattr(self._objects[packet.name].object, packet.attr)).to_sock(sock)
                    except Exception as err:
                        msg.ProxyExceptionResponse(err).to_sock(sock)
Auf der Clientseite bekomme ich dann ein tuple welches den Klassennamen, den Modulnamen (wenn vorhanden, sonst None) und args.

Das ist z.B. meine Testklasse:

Code: Alles auswählen

class T(object):
    def __init__(self):
        self.val = 3
    def t1(self):
        print("bla")
    @property
    def t2(self):
        if self.val > 6:
            raise NotImplementedError("bla", "pups")
        else:
            self.val += 1
Dann ist das tuple auf der Clientseite ("NotImplementedError", None, ("bla", "pups"))
Wie kann ich dann daraus eine neue Exception instanzieren und werfen?

(Ich will nicht die ganze Exception picklen und die durch den Socket jagen.)

MfG
bubble
rotten_corpse
User
Beiträge: 3
Registriert: Freitag 13. Dezember 2013, 22:31

Ich Hohlbirne, 2 Tage googlen bevor ich mich hier melde und keine 2h danach hab ich die Lösung:

Code: Alles auswählen

    def reproduce_exc(module, exception, args):
        if module:
            if module in sys.modules:
                return getattr(sys.modules[module], exception)(*args)
            else:
                try:
                    return getattr(importlib.import_module(module), exception)(*args)
                except ImportError as err:
                    return errors.ExceptionNotReproducable(module + "." + exception + " not reproducable (" + repr(args) +")")
        else:
            return getattr(sys.modules["builtins"], exception)(*args)
BlackJack

@rotten_corpse: Ich würde das vereinfachen und mir das Nachsehen in `sys.modules` sparen. Das macht der Importmechanismus sowieso. An der Stelle kann man dann auch den Fall bei nicht angegebenen Modul vereinfachen. Ungetestet:

Code: Alles auswählen

def reproduce_exc(module_name, exception, args):
    try:
        module = importlib.import_module(
            module_name if module_name else 'builtins'
        )
    except ImportError:
        return errors.ExceptionNotReproducable(
            '{0}.{1} not reproducable ({2!r})'
                .format(module_name, exception, args)
        )
    else:
        return getattr(module, exception)(*args)
rotten_corpse
User
Beiträge: 3
Registriert: Freitag 13. Dezember 2013, 22:31

[quote="BlackJack"]@rotten_corpse: Ich würde das vereinfachen und mir das Nachsehen in `sys.modules` sparen. Das macht der Importmechanismus sowieso. An der Stelle kann man dann auch den Fall bei nicht angegebenen Modul vereinfachen. Ungetestet [...]

Funktioniert einwandfrei und ist um einiges übersichtlicher als mein Code, danke!

Das Konstrukt kannte ich bis dato noch gar nicht:

Code: Alles auswählen

module_name if module_name else 'builtins'
Antworten