Re: [Python] Info su cancellazione traceback

2022-11-19 Per discussione Matteo Boscolo

On 19/11/2022 10:47, Marco Giusti wrote:

On 19.11.2022 08:45, Matteo Boscolo wrote:

Buongiorno a tutti,

vorrei cancellare il traceback di python e mostrare solo il mio raise,
questa cosa mi serve per evitare che lo stack dell'errore venga visto
in console.

ho provato con questo decoratore

def avoid_traceback(message=''):
    ''' call a function a number of times '''
    def decorate(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
    try:
    result = fn(*args, **kwargs)
    except Exception as ex:
    if message:
    raise Exception(message)
    raise Exception("Error on method %s" % fn.__name__)
    return result
    return wrapper
    return decorate


che funziona, ma il traceback resta attivo, nel senso che se metto

traceback.print_exc()

mi vedo tutto lo stack dell'errore:

Traceback (most recent call last):
  File "/media/OneTDisk/workspace/test.py", line 133, in wrapper
    result = fn(*args, **kwargs)
  File "/media/OneTDisk/workspace/test.py", line 218, in rise
    raise Exception("rise")
Exception: rise


potete provare con questo esempietto qua:

class A(object):
    def __init__(self):
    pass

    @avoid_traceback("errore generico")#
    def rise1(self):
    return self.rise()

    @avoid_traceback("errore generico")#
    def rise(self):
    raise Exception("rise")
a=A()
a.rise1()
traceback.print_exc()

ho trovato in rete

https://www.programcreek.com/python/example/119512/traceback.clear_frames 



ma sembra che non funzioni..

qualche idea ?



Ciao Matteo,

vorrei premettere che non trovo sia una buona idea nascondere
informazioni quando si ha a che fare con delle eccezioni, anzi, piu'
informazioni ci sono e meglio e'. Comunque, usa il costrutto

    raise exception from None

Quando lanci un'eccezione al momento in cui ne stai gia' gestendo
un'altra, le due eccezioni sono concatenate in due punti: __context__ e
__cause__. Il primo attributo e' settato automaticamente e per
sovrascriverlo hai bisogno di un ulteriore blocco try/except. Non farlo,
perche' per visualizzare il traceback e' usato __suppress_context__.

Se il valore e' False, allora viene visualizzato __cause__ o
__context__, se il valore e' True, allora la precedente eccezione non e'
visualizzata. Usando "raise ... from None: ottieni gia' quello
che desideri: __cause__ e' settato to None e __suppress_context__ e'
settato to True.

Ecco qualche esempio usando sempre questo codice e usando il decoratore
"avoid_traceback" solo sul metodo "rise1".

    a = A()
    try:
    a.rise1()
    except Exception as exc:
    print(f"exc.__cause__: {exc.__cause__}")
    print(f"exc.__suppress_context__: {exc.__suppress_context__}")
    print(f"exc.__context__: {exc.__context__}")
    raise
    traceback.print_exc()


Esempio 1, lasciando il decoratore invariato:

    $ python3 hide_traceback.py
    exc.__cause__: None
    exc.__suppress_context__: False
    exc.__context__: rise
    Traceback (most recent call last):
  File "/home/marco/hide_traceback.py", line 11, in wrapper
    result = fn(*args, **kwargs)
  File "/home/marco/hide_traceback.py", line 27, in rise1
    return self.rise()
  File "/home/marco/hide_traceback.py", line 30, in rise
    raise Exception("rise")
    Exception: rise

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
  File "/home/marco/hide_traceback.py", line 35, in 
    a.rise1()
  File "/home/marco/hide_traceback.py", line 14, in wrapper
    raise Exception(message)
    Exception: errore generico

Esempio 2, usando raise ... from None

    $ python3 hide_traceback.py
    exc.__cause__: None
    exc.__suppress_context__: True
    exc.__context__: rise
    Traceback (most recent call last):
  File "/home/marco/hide_traceback.py", line 35, in 
    a.rise1()
  File "/home/marco/hide_traceback.py", line 14, in wrapper
    raise Exception(message) from None
    Exception: errore generico

Esempio 3, usando un ulteriore blocco try/catch


    ...
    try:
    try:
    result = fn(*args, **kwargs)
    except Exception as ex:
    if message:
    raise Exception(message) from None
    raise Exception("Error on method %s" % fn.__name__) from None
    except Exception as exc:
    exc.__context__ = None
    raise exc

    $ python3 hide_traceback.py
    exc.__cause__: None
    exc.__suppress_context__: True
    exc.__context__: None
    Traceback (most recent call last):
  File "/home/marco/hide_traceback.py", line 39, in 
    a.rise1()
  File "/home/marco/hide_traceback.py", line 19, in wrapper
    raise exc
  File "/home/marco/hide_traceback.py", line 15, in wrapper
    raise Exception(message) from None
    Exception: errore generico


Grazie mille Marco per le preziose informazioni.

Questo codice fa 

Re: [Python] Info su cancellazione traceback

2022-11-19 Per discussione Marco Giusti

On 19.11.2022 08:45, Matteo Boscolo wrote:

Buongiorno a tutti,

vorrei cancellare il traceback di python e mostrare solo il mio raise,
questa cosa mi serve per evitare che lo stack dell'errore venga visto
in console.

ho provato con questo decoratore

def avoid_traceback(message=''):
    ''' call a function a number of times '''
    def decorate(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
    try:
    result = fn(*args, **kwargs)
    except Exception as ex:
    if message:
    raise Exception(message)
    raise Exception("Error on method %s" % fn.__name__)
    return result
    return wrapper
    return decorate


che funziona, ma il traceback resta attivo, nel senso che se metto

traceback.print_exc()

mi vedo tutto lo stack dell'errore:

Traceback (most recent call last):
  File "/media/OneTDisk/workspace/test.py", line 133, in wrapper
    result = fn(*args, **kwargs)
  File "/media/OneTDisk/workspace/test.py", line 218, in rise
    raise Exception("rise")
Exception: rise


potete provare con questo esempietto qua:

class A(object):
    def __init__(self):
    pass

    @avoid_traceback("errore generico")#
    def rise1(self):
    return self.rise()

    @avoid_traceback("errore generico")#
    def rise(self):
    raise Exception("rise")
a=A()
a.rise1()
traceback.print_exc()

ho trovato in rete

https://www.programcreek.com/python/example/119512/traceback.clear_frames

ma sembra che non funzioni..

qualche idea ?



Ciao Matteo,

vorrei premettere che non trovo sia una buona idea nascondere
informazioni quando si ha a che fare con delle eccezioni, anzi, piu'
informazioni ci sono e meglio e'. Comunque, usa il costrutto

raise exception from None

Quando lanci un'eccezione al momento in cui ne stai gia' gestendo
un'altra, le due eccezioni sono concatenate in due punti: __context__ e
__cause__. Il primo attributo e' settato automaticamente e per
sovrascriverlo hai bisogno di un ulteriore blocco try/except. Non farlo,
perche' per visualizzare il traceback e' usato __suppress_context__.

Se il valore e' False, allora viene visualizzato __cause__ o
__context__, se il valore e' True, allora la precedente eccezione non e'
visualizzata. Usando "raise ... from None: ottieni gia' quello
che desideri: __cause__ e' settato to None e __suppress_context__ e'
settato to True.

Ecco qualche esempio usando sempre questo codice e usando il decoratore
"avoid_traceback" solo sul metodo "rise1".

a = A()
try:
a.rise1()
except Exception as exc:
print(f"exc.__cause__: {exc.__cause__}")
print(f"exc.__suppress_context__: {exc.__suppress_context__}")
print(f"exc.__context__: {exc.__context__}")
raise
traceback.print_exc()


Esempio 1, lasciando il decoratore invariato:

$ python3 hide_traceback.py
exc.__cause__: None
exc.__suppress_context__: False
exc.__context__: rise
Traceback (most recent call last):
  File "/home/marco/hide_traceback.py", line 11, in wrapper
result = fn(*args, **kwargs)
  File "/home/marco/hide_traceback.py", line 27, in rise1
return self.rise()
  File "/home/marco/hide_traceback.py", line 30, in rise
raise Exception("rise")
Exception: rise

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/marco/hide_traceback.py", line 35, in 
a.rise1()
  File "/home/marco/hide_traceback.py", line 14, in wrapper
raise Exception(message)
Exception: errore generico

Esempio 2, usando raise ... from None

$ python3 hide_traceback.py
exc.__cause__: None
exc.__suppress_context__: True
exc.__context__: rise
Traceback (most recent call last):
  File "/home/marco/hide_traceback.py", line 35, in 
a.rise1()
  File "/home/marco/hide_traceback.py", line 14, in wrapper
raise Exception(message) from None
Exception: errore generico

Esempio 3, usando un ulteriore blocco try/catch


...
try:
try:
result = fn(*args, **kwargs)
except Exception as ex:
if message:
raise Exception(message) from None
raise Exception("Error on method %s" % fn.__name__) from 
None

except Exception as exc:
exc.__context__ = None
raise exc

$ python3 hide_traceback.py
exc.__cause__: None
exc.__suppress_context__: True
exc.__context__: None
Traceback (most recent call last):
  File "/home/marco/hide_traceback.py", line 39, in 
a.rise1()
  File "/home/marco/hide_traceback.py", line 19, in wrapper
raise exc
  File "/home/marco/hide_traceback.py", line 15, in wrapper
raise Exception(message) from None
Exception: errore generico

___
Python mailing list
Python@lists.python.it