Python: evitar la evaluación de cortocircuitos

Este es un problema que se me ocurrió mientras trabajaba en un proyecto de Django. Se trata de validación de formularios.

En Django, cuando tiene un formulario enviado, puede llamar a is_valid() en el objeto de formulario correspondiente para activar la validación y devolver un valor booleano. Entonces, normalmente tienes un código así dentro de tus funciones de visualización:

 if form.is_valid(): # code to save the form data 

is_valid() no solo valida los datos del formulario, sino que también agrega mensajes de error al objeto del formulario que luego puede mostrarse al usuario.

En una página, uso dos formularios juntos y también quiero que los datos se guarden solo si ambos formularios contienen datos válidos. Eso significa que tengo que llamar a is_valid () en ambos formularios antes de ejecutar el código para guardar los datos. La forma más obvia:

 if form1.is_valid() and form2.is_valid(): # ... 

no funcionará debido a la evaluación de cortocircuito de los operadores lógicos. Si form1 no es válido, form2 no se evaluará y faltarán sus mensajes de error.

    Eso es sólo un ejemplo. Que yo sepa, no hay una alternativa codiciosa and / or en otros idiomas (es decir, Smalltalk). Puedo imaginar que el problema ocurre en diferentes circunstancias (y no solo en Python). Las soluciones en las que podría pensar son todas torpes (nested ifs, asignando los valores de retorno a las variables locales y usándolos en la statement if). Me gustaría conocer la forma pythonica de resolver este tipo de problemas.

    ¡Gracias por adelantado!

    ¿Qué tal algo como:

     if all([form1.is_valid(), form2.is_valid()]): ... 

    En un caso general, se podría utilizar una lista-comprensión de manera que los resultados se calculen por adelantado (a diferencia de una expresión generadora que se usa comúnmente en este contexto). p.ej:

     if all([ form.is_valid() for form in (form1,form2) ]) 

    Esto también se adaptará a un número arbitrario de condiciones … El único problema es que todos deben estar conectados por ” and “, en contraposición a if foo and bar or baz: ...

    (para un circuito sin cortocircuito or , puede usar any lugar de all ).

    Simplemente puede usar el operador binario, que hará un AND lógico sin cortocircuito en bools.

     if form1.is_valid() & form2.is_valid(): ...