top outer modules modulenotfounderror from beyond attempted python import python-internals shadowing

outer - Sombreado de importación Python diferente entre 3.4.6 y 3.5.2



python modules (1)

El sombreado de importación de Python parece ser diferente entre las versiones 3.4.6 y 3.5.2:

$ cat time.py from time import time $ pyenv global 3.4.6 $ python -V Python 3.4.6 $ python time.py Traceback (most recent call last): File "time.py", line 1, in <module> from time import time File "/home/vagrant/tmp/time.py", line 1, in <module> from time import time ImportError: cannot import name ''time'' $ pyenv global 3.5.2 $ python -V Python 3.5.2 $ python time.py $ echo no error no error

Pregunta 1: ¿Por qué es ... esas cosas?

Pregunta 2: ¿hay algo en un registro de cambios sobre eso? No puedo encontrar nada ...


La documentación dice que

Cuando se importa un módulo llamado spam , el intérprete primero busca un módulo integrado con ese nombre . Si no se encuentra, busca un archivo llamado spam.py en una lista de directorios dada por la variable sys.path .

(énfasis mío)

time no era un módulo de módulo incorporado en Python 3.4, pero eso cambió en Python 3.5:

me@temp:~$ python3.4 -c ''import sys; print("time" in sys.builtin_module_names)'' False me@temp:~$ python3.5 -c ''import sys; print("time" in sys.builtin_module_names)'' True

Puede ver el parche que introdujo el cambio aquí (relacionado con el número 5309 ). Teniendo en cuenta que el registro de cambios menciona el problema 5309 , pero no dice nada re. el módulo de time , es seguro decir que el cambio fue un efecto secundario y es un detalle de implementación de CPython.

Dado que el time no es un módulo incorporado en CPython 3.4, y el primer directorio en sys.path es el directorio actual de scripts, from time import time intenta importar el atributo de time de su archivo time.py , pero falla y arroja el ImportError .

En CPython 3.5 time es un módulo incorporado. De acuerdo con la cita anterior, la ejecución from time import time importa con éxito el módulo incorporado, sin buscar módulos en sys.path .

Ambas versiones de CPython generarán el mismo error si sombrea un módulo no incorporado de la biblioteca estándar, como inspect :

me@temp:~$ cat inspect.py from inspect import signature me@temp:~$ python3.4 -c ''import inspect'' Traceback (most recent call last): File "<string>", line 1, in <module> File "/home/me/inspect.py", line 1, in <module> from inspect import signature ImportError: cannot import name ''signature'' me@temp:~$ python3.5 -c ''import inspect'' Traceback (most recent call last): File "<string>", line 1, in <module> File "/home/me/inspect.py", line 1, in <module> from inspect import signature ImportError: cannot import name ''signature''