from example another python python-import

python - example - ¿Cómo lidiar con gracia con las importaciones de funciones futuras fallidas(__future__) debido a la versión anterior del intérprete?



python import from parent directory (3)

"Me gustaría informar al usuario que necesitan volver a ejecutar el programa con Python> = 2.6 y tal vez proporcionar algunas instrucciones sobre cómo hacerlo".

¿No es eso para lo que es un archivo README?

Aquí está tu alternativa. Una "envoltura": una pequeña mancha de Python que verifica el entorno antes de ejecutar su AOP objetivo.

Archivo: appwrapper.py

import sys major, minor, micro, releaselevel, serial = sys.version_info if (major,minor) <= (2,5): # provide advice on getting version 2.6 or higher. sys.exit(2) import app app.main()

Qué significa "importación directa". Puede examinar el contenido de __future__ . Todavía está obligado por el hecho de que a from __future__ import print_function es información para el compilador, pero puede hurgar antes de importar el módulo que hace el trabajo real.

import __future__, sys if hasattr(__future__, ''print_function''): # Could also check sys.version_info >= __future__. print_function.optional import app app.main() else: print "instructions for upgrading"

¿Cómo maneja con gracia las importaciones de características futuras fallidas? Si un usuario se está ejecutando con Python 2.5 y la primera declaración en mi módulo es:

from __future__ import print_function

La compilación de este módulo para Python 2.5 fallará con un:

File "__init__.py", line 1 from __future__ import print_function SyntaxError: future feature print_function is not defined

Me gustaría informar al usuario que necesitan volver a ejecutar el programa con Python> = 2.6 y tal vez proporcionar algunas instrucciones sobre cómo hacerlo. Sin embargo, para citar PEP 236 :

Las únicas líneas que pueden aparecer antes de una future_statement son:

  • El módulo docstring (si lo hay).
  • Comentarios.
  • Líneas en blanco.
  • Otros future_statements.

Entonces no puedo hacer algo como:

import __future__ if hasattr(__future__, ''print_function''): from __future__ import print_function else: raise ImportError(''Python >= 2.6 is required'')

Porque cede:

File "__init__.py", line 4 from __future__ import print_function SyntaxError: from __future__ imports must occur at the beginning of the file

Este fragmento del PEP parece dar la esperanza de hacerlo en línea:

P: Quiero ajustar future_statements en try / except blocks, para poder usar código diferente dependiendo de qué versión de Python estoy ejecutando. ¿Por qué no puedo?

A: ¡Lo siento! try / except es una característica de tiempo de ejecución; future_statements son principalmente trucos en tiempo de compilación, y tu try / except ocurre mucho después de que el compilador haya terminado. Es decir, cuando intenta / exceptúa, la semántica vigente para el módulo ya está lista. Dado que try / except no lograría lo que parece que debería lograr, simplemente no está permitido. También queremos que estas declaraciones especiales sean muy fáciles de encontrar y de reconocer.

Tenga en cuenta que puede importar __future__ directamente, y usar la información que contiene, junto con sys.version_info, para averiguar dónde se encuentra el lanzamiento que está ejecutando en relación con el estado de una función determinada.

Ideas?


Simplemente ponga un comentario en la misma línea con la "from __future__ import ..." , como esta:

from __future__ import print_function, division # We require Python 2.6 or later

Como Python muestra la línea que contiene el error, si intenta ejecutar el módulo con Python 2.5 obtendrá un buen error descriptivo:

from __future__ import print_function, division # We require Python 2.6 or later SyntaxError: future feature print_function is not defined


Un método bastante hacky pero simple que he usado antes es explotar el hecho de que los literales de bytes se introdujeron en Python 2.6 y usan algo así cerca del inicio del archivo:

b''This module needs Python 2.6 or later. Please do xxx.''

Esto es inofensivo en Python 2.6 o posterior, pero un SyntaxError en cualquier versión anterior. Cualquier persona que intente compilar su archivo recibirá un error, pero también recibirá el mensaje que quiera.

Puede pensar que como tendrá que tener esta línea después de su from __future__ import print_function entonces será la importación la que generará SyntaxError y no podrá ver el útil mensaje de error, pero curiosamente el último error tiene prioridad. Sospecho que como el error de la importación no es realmente un error de sintaxis en sí mismo, no se genera en el primer pase de compilación, por lo que los errores de sintaxis reales aparecen primero (pero supongo).

Esto puede no cumplir con los criterios para ser ''elegante'', y es muy específico de Python 2.6, pero es rápido y fácil de hacer.