python unicode doctest

¿Cómo incluyo cadenas Unicode en doctests de Python?



(5)

Estoy trabajando en un código que tiene que manipular cadenas de Unicode. Estoy tratando de escribir documentos para ello, pero estoy teniendo problemas. El siguiente es un ejemplo mínimo que ilustra el problema:

# -*- coding: utf-8 -*- def mylen(word): """ >>> mylen(u"áéíóú") 5 """ return len(word) print mylen(u"áéíóú")

Primero ejecutamos el código para ver la salida esperada de print mylen(u"áéíóú") .

$ python mylen.py 5

A continuación, ejecutamos doctest en él para ver el problema.

$ python -m 5 ********************************************************************** File "mylen.py", line 4, in mylen.mylen Failed example: mylen(u"áéíóú") Expected: 5 Got: 10 ********************************************************************** 1 items had failures: 1 of 1 in mylen.mylen ***Test Failed*** 1 failures.

Entonces, ¿cómo puedo probar que mylen(u"áéíóú") evalúa a 5?


Como ya se mencionó, debe asegurarse de que sus cadenas de documentación sean Unicode.

Si puede cambiar a Python 3, entonces funcionaría automáticamente allí, ya que tanto la codificación de origen ya es utf-8 y el tipo de cadena predeterminado es Unicode.

Para lograr lo mismo en Python 2, debe mantener la coding: utf-8 junto a la cual puede prefijar todas las cadenas de documentación con u , o simplemente agregar

from __future__ import unicode_literals


Esto parece ser un problema conocido y aún no resuelto en Python. Ver temas abiertos here y here .

No es sorprendente que se pueda modificar para que funcione correctamente en Python 3, ya que todas las cadenas son Unicode:

def mylen(word): """ >>> mylen("áéíóú") 5 """ return len(word) print(mylen("áéíóú"))


Mi solución fue escapar de los caracteres Unicode, como u ''/ xe1 / xe9 / xed / xf3 / xfa''. Sin embargo, no fue tan fácil de leer, pero mis pruebas solo tenían algunos caracteres no ASCII, por lo que en esos casos pongo la descripción a un lado como un comentario, como "# n con tilde".


Python 2.6.6 no entiende muy bien la salida de Unicode, pero esto puede solucionarse usando:

  • truco ya descrito con sys.setdefaultencoding("UTF-8")
  • Unicode Docstring (ya mencionado anteriormente también, muchas gracias)
  • Y print declaración.

En mi caso, esta cadena de documentación dice que la prueba está rota:

def beatiful_units(*units): u''''''Returns nice string like ''erg/(cm² sec)''. >>> beatiful_units((''erg'', 1), (''cm'', -2), (''sec'', -1)) u''erg/(cm² sec)'' ''''''

con mensaje de "error"

Failed example: beatiful_units((''erg'', 1), (''cm'', -2), (''sec'', -1)) Expected: u''erg/(cm² sec)'' Got: u''erg/(cm/xb2 sec)''

Usando la print podemos arreglar eso:

def beatiful_units(*units): u''''''Returns nice string like ''erg/(cm² sec)''. >>> print beatiful_units((''erg'', 1), (''cm'', -2), (''sec'', -1)) erg/(cm² sec) ''''''


Si quieres cadenas Unicode, ¡tienes que usar cadenas de documentación Unicode! ¡Cuidado con el u !

# -*- coding: utf-8 -*- def mylen(word): u""" <----- SEE ''u'' HERE >>> mylen(u"áéíóú") 5 """ return len(word) print mylen(u"áéíóú")

Esto funcionará, siempre que pasen las pruebas. Para Python 2.x necesitas otro truco para hacer que el modo de prueba documental funcione o para obtener las respuestas correctas cuando las pruebas fallan:

if __name__ == "__main__": import sys reload(sys) sys.setdefaultencoding("UTF-8") import doctest doctest.testmod()

¡NÓTESE BIEN! Utilice siempre setdefaultencoding para fines de depuración. Lo aceptaría para uso documental, pero no en ningún lugar de su código de producción.