Ejecutando JSON a través de eval () de Python?

Dejando de lado las mejores prácticas, ¿hay alguna razón convincente para no hacer esto?

Estoy escribiendo un enlace de post-confirmación para usar con un proyecto de Google Code, que proporciona datos de confirmación a través de un objeto JSON. GC proporciona un token de autenticación HMAC junto con la solicitud (fuera de los datos JSON), por lo que al validar ese token, tengo una gran confianza en que los datos JSON son benignos (ya que no tiene sentido desconfiar de Google) y son válidos.

Mis propias (breves) investigaciones sugieren que JSON es Python completamente válido, con la excepción de la secuencia de escape "\/" , que GC no parece generar.

Entonces, como estoy trabajando con Python 2.4 (es decir, sin módulo json ), eval() parece realmente tentador.

Edit: Para el registro, no estoy preguntando si es una buena idea. Soy muy consciente de que no lo es, y dudo mucho que alguna vez use esta técnica para proyectos futuros, incluso si termino usándola para este. Solo quería asegurarme de saber en qué tipo de problemas me encontraré si lo hago. 🙂

Si te sientes cómodo con tu script funcionando bien por un tiempo, y luego fallas al azar en algún caso poco claro, me gustaría ir con eval.

Si es importante que su código sea robusto, me tomaría el tiempo de agregar simplejson. No necesita la parte C para las aceleraciones, por lo que realmente no debería ser difícil volcar algunos archivos .py en un directorio en algún lugar.

Como ejemplo de algo que podría morderte, JSON usa Unicode y simplejson devuelve Unicode, mientras que eval devuelve str:

 >>> simplejson.loads('{"a":1, "b":2}') {u'a': 1, u'b': 2} >>> eval('{"a":1, "b":2}') {'a': 1, 'b': 2} 

Edición: un mejor ejemplo de donde eval () se comporta de manera diferente:

 >>> simplejson.loads('{"X": "\uabcd"}') {u'X': u'\uabcd'} >>> eval('{"X": "\uabcd"}') {'X': '\\uabcd'} >>> simplejson.loads('{"X": "\uabcd"}') == eval('{"X": "\uabcd"}') False 

Edición 2: vi otro problema hoy señalado por SilentGhost: eval no maneja verdadero -> Verdadero, falso -> Falso, nulo -> Ninguno correctamente.

 >>> simplejson.loads('[false, true, null]') [False, True, None] >>> eval('[false, true, null]') Traceback (most recent call last): File "", line 1, in  File "", line 1, in  NameError: name 'false' is not defined >>> 

El punto de las mejores prácticas es que, en la mayoría de los casos, es una mala idea ignorarlas. Si yo fuera tú, usaría un analizador para analizar JSON en Python. Pruebe simplejson , fue muy sencillo para analizar JSON la última vez que lo probé y afirma ser compatible con Python 2.4.

No estoy de acuerdo en que no tenga sentido desconfiar de Google. No desconfiaría de ellos, pero verificaría los datos que obtienes de ellos. La razón por la que realmente usaría un analizador JSON es correcta en tu pregunta:

Mis propias (breves) investigaciones sugieren que JSON es Python completamente válido, con la excepción de la secuencia de escape “/”, que GC no parece generar.

¿Qué te hace pensar que Google Code nunca generará una secuencia de escape como esa?

El análisis es un problema resuelto si utiliza las herramientas adecuadas. Si intentas tomar atajos como este, eventualmente serás mordido por suposiciones incorrectas, o harás algo como intentar juntar un analizador con lógica de expresiones regulares y lógica booleana cuando ya existe un analizador para el idioma que elijas.

Una diferencia importante es que un booleano en JSON es true | false , pero Python usa True | False

La razón más importante para no hacer esto puede ser generalizada: eval nunca debe usarse para interpretar entradas externas, ya que esto permite la ejecución de código arbitrario.

eval JSON es un poco como intentar ejecutar XML a través de un comstackdor de C ++.

eval está destinado a evaluar el código de Python. Aunque hay algunas similitudes sintácticas, JSON no es un código Python . Diablos, no solo no es el código de Python , sino que no es un código para empezar. Por lo tanto, incluso si puede salirse con la suya para su caso de uso, diría que es una mala idea conceptualmente. Python es una manzana, JSON es una soda con sabor a naranja.