2010-09-27 21 views
31

Escribo de la siguiente manera, en la cual intento producir un mensaje de error decente cuando comparo dos bloques de líneas múltiples de texto Unicode. El método interior que hace la comparación plantea una afirmación, pero la explicación por defecto es inútil para mí¿Cómo cambiar el mensaje en Python AssertionError?

tengo que añadir algo de código como esta a continuación:

def assert_long_strings_equal(one, other): 
    lines_one = one.splitlines() 
    lines_other = other.splitlines() 
    for line1, line2 in zip(lines_one, lines_other): 
     try: 
      my_assert_equal(line1, line2) 
     except AssertionError, error: 
      # Add some information to the printed result of error??! 
      raise 

no puedo encontrar la manera de cambiar el Mensaje de error impreso en el assertionerror que atrapo. Siempre obtengo AssertionError: u'something' != 'something else', que solo muestra la primera línea de la salida.

¿Cómo puedo cambiar el mensaje de afirmación para imprimir lo que quiera?

Si es relevante, estoy usando nose para ejecutar la prueba.

+0

Solo para aclarar, me doy cuenta de que la captura de un error de aserción es extraña. Da la casualidad de que 'my_assert_equal' es un poco profundo y no quiero meterme con eso. –

+1

Solo para señalar, debe tener 'excepto' no' atrapar'. Aunque estoy seguro de que es solo un error tipográfico: p – katrielalex

Respuesta

39

Uso e.args, e.message está en desuso.

try: 
    assert False, "Hello!" 
except AssertionError as e: 
    e.args += ('some other', 'important', 'information', 42) 
    raise 

Esto conserva la trazabilidad original. Su última parte tendrá el aspecto siguiente:

AssertionError: ('Hello!', 'some other', 'important', 'information', 42) 

funciona tanto en Python 2.7 y Python 3.

+0

Esto solo provoca un error de tipo cuando lo pruebo en 2.7. – philologon

+0

¿Qué tipo de error? Estaba usando 2.7 al escribir la respuesta. –

+0

@philologon Acabo de probar la solución (copiar y pegar exactamente mi respuesta) tanto en Python 2.7.10 como en Python 3.5.1 y funciona como se esperaba. Mi respuesta ha sido downvoted, pero no veo ninguna razón por qué. –

0

Puede pasar el mensaje deseado al crear la excepción.

raise AssertionError(line1 + ' != ' + line2) 

Espero que esto ayude.

+0

Eso no es lo que significa el OP; 'AssertionError' es (generalmente) provocado por la declaración' assert'. – katrielalex

+0

No estoy seguro ... pero si está envuelto con una declaración 'if' en lugar de usar' assert' podría ser aceptable. De esta forma, podría usar un bloque 'if else' y un repliegue en un AssertionError con un mensaje personalizado. –

48
assert expression, info 

Por ejemplo,

>>> assert False, "Oopsie" 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AssertionError: Oopsie 

De los docs:

instrucciones ASSERT son una manera conveniente para insertar las afirmaciones de depuración en un programa :

assert_stmt ::= "assert" expression 
["," expression] 

La forma simple, assert expression, es equivalente a

if __debug__: 
    if not expression: 
     raise AssertionError 

La forma extendida

assert expression1, expression2 

es equivalente a

if __debug__: 
    if not expression1: 
     raise AssertionError(expression2) 

Estas equivalencias asumen que __debug__ y AssertionError se refieren a las variables incorporadas con esos nombres . En la implementación actual, , la variable incorporada __debug__ es Verdadero en circunstancias normales, False cuando se solicita la optimización (opción de línea de comando -O). El generador de código actual no emite ningún código para una declaración de aserción cuando la optimización es solicitada en tiempo de compilación. Tenga en cuenta que no es necesario incluir el código fuente para la expresión que falló en el mensaje de error; Se mostrará como parte de la pila trace.

+1

Tenga en cuenta que también puede incrustar nuevas líneas en la expresión de cadena 'info' para que se vean bien cuando se muestran. – martineau

+0

También tenga en cuenta que puede agregar información adicional a la expresión de cadenas mediante la interpolación de cadenas de Python y las operaciones de formateo de cadenas más nuevas. – martineau

+0

Plantear una excepción en general no es un problema. Captura, modifica y vuelve a plantear una expresión, lo que pregunté. –

5

Desea tomar la excepción atrapada, convertirla en una cadena, combinarla con alguna información de cadena adicional y generar una nueva excepción.

x = 3 
y = 5 
try: 
    assert(x == y) 
except AssertionError, e: 
    raise(AssertionError("Additional info. %s"%e)) 
+4

No vi ninguna de las respuestas publicadas ofrecer la solución general de cómo agregar información a una excepción y volver a subir con la información original y adicional, que pensé que era lo que el OP estaba pidiendo . –

+0

Russel tiene razón, este es el tipo de cosa que estaba buscando. –

+13

Esto pierde la trazabilidad. – ninjagecko

5

Con este método pude editar el mensaje y todavía tienen el seguimiento de la pila (+ cualquier otra información) visible. Además, las nuevas líneas se muestran a la derecha.

try: 
    my_assert_equal(line1, line2) 
except AssertionError as e: 
    message = e.args[0] 
    message += "\nThis appends the default message and can have newlines" 
    e.args = (message,) #wrap it up in new tuple 
    raise 
+0

Esto incluye nuevas líneas y no tiene que copiar en '' + = '': '' e.args = (u "% s \ n% s"% (e.args [0], addl_message),) '' –

Cuestiones relacionadas