# `imp` — Acceda a import internamente

Código fuente: Lib/imp.py

Obsoleto desde la versión 3.4, se eliminará en la versión 3.12: El módulo `imp` está obsoleto en favor de `importlib`.

Este módulo proporciona una interfaz a los mecanismos utilizados para implementar la sentencia `import`. Define las siguientes constantes y funciones:

imp.get_magic()

  Retorna el valor de la cadena de caracteres mágica que se utiliza para reconocer archivos de código compilados por bytes (archivos `.pyc`). (Este valor puede ser diferente para cada versión de Python).

  Obsoleto desde la versión 3.4: Utilice `importlib.util.MAGIC_NUMBER` en su lugar.

imp.get_suffixes()

  Retorna una lista de tuplas de 3 elementos, cada una de las cuales describe un tipo particular de módulo. Cada triple tiene la forma `(suffix, mode, type)`, donde suffix es una cadena de caracteres que se agregará al nombre del módulo para formar el nombre de archivo a buscar, mode es la cadena de caracteres de modo para pasar a la función incorporada `open()` para abrir el archivo (esto puede ser `'r'` para archivos de texto o `'rb'` para archivos binarios), y type es el tipo de archivo, que tiene uno de los valores `PY_SOURCE`, `PY_COMPILED`, o `C_EXTENSION`, que se describen a continuación.

  Obsoleto desde la versión 3.3: Utilice las constantes definidas en `importlib.machinery` en su lugar.

imp.find_module(name[, path])

  Intente encontrar el módulo name. Si se omite path o `None`, se busca la lista de nombres de directorio dados por `sys.path`, pero primero se buscan algunos lugares especiales: la función intenta encontrar un módulo integrado con el nombre dado (`C_BUILTIN`), a continuación, un módulo congelado (`PY_FROZEN`), y en algunos sistemas algunos otros lugares se buscan también (en Windows, se ve en el registro que puede apuntar a un archivo específico).

  De lo contrario, path debe ser una lista de nombres de directorio; cada directorio se busca archivos con cualquiera de los sufijos retornados por `get_suffixes()` arriba. Los nombres no válidos de la lista se omiten silenciosamente (pero todos los elementos de lista deben ser cadenas).

  Si la búsqueda se realiza correctamente, el valor retornado es una tupla de 3 elementos `(file, pathname, description)`:

  file es un abierto file object posicionado al principio, pathname es el nombre de ruta del archivo encontrado, y description es una tupla de 3 elementos tal como se encuentra en la lista retornada por `get_suffixes()` que describe el tipo de módulo encontrado.

  Si el módulo no vive en un archivo, el archivo file retornado es `None`, pathname es la cadena vacía y la tupla description contiene cadenas vacías para su sufijo y modo; el tipo de módulo se indica como se indica entre paréntesis arriba. Si la búsqueda no se realiza correctamente, se provoca `ImportError`. Otras excepciones indican problemas con los argumentos o el entorno.

  Si el módulo es un paquete, file es `None`, pathname es la ruta de acceso del paquete y el último elemento de la tupla description es `PKG_DIRECTORY`.

  Esta función no controla los nombres de módulo jerárquico (nombres que contienen puntos). Para encontrar P.M, es decir, submódulo M del paquete P, use `find_module()` y `load_module()` para buscar y cargar el paquete P, y luego use `find_module()` con el argumento path establecido en `P.__path__`. Cuando P tenga un nombre punteado, aplique esta receta de forma recursiva.

  Obsoleto desde la versión 3.3: Utilice `importlib.util.find_spec()` en su lugar a menos que se requiera compatibilidad con Python 3.3, en cuyo caso use `importlib.find_loader()`. Para ver el uso del caso anterior, consulte la sección Ejemplos de la documentación `importlib`.

imp.load_module(name, file, pathname, description)

  Cargue un módulo que fue encontrado anteriormente por `find_module()` (o por una búsqueda realizada de otro modo que produce resultados compatibles). Esta función hace más que importar el módulo: si el módulo ya estaba importado, se recargará el módulo! El argumento name indica el nombre completo del módulo (incluido el nombre del paquete, si se trata de un submódulo de un paquete). El argumento file es un archivo abierto y pathname es el nombre de archivo correspondiente; pueden ser `None` y `''`, respectivamente, cuando el módulo es un paquete o no se carga desde un archivo. El argumento description es una tupla, como sería retornada por `get_suffixes()`, que describe qué tipo de módulo se debe cargar.

  Si la carga se realiza correctamente, el valor retornado es el objeto modulo; de lo contrario, se produce una excepción (normalmente `ImportError`).

  Importante: el autor de la llamada es responsable de cerrar el argumento file, si no era `None`, incluso cuando se genera una excepción. Esto se hace mejor usando una declaración `try` … `finally`.

  Obsoleto desde la versión 3.3: Si se utiliza anteriormente junto con `imp.find_module()` considere usar `importlib.import_module()`, de lo contrario utilice el cargador retornado por el reemplazo que eligió para `imp.find_module()`. Si llamó a `imp.load_module()` y funciones relacionadas directamente con argumentos de ruta de archivo, utilice una combinación de `importlib.util.spec_from_file_location()` y `importlib.util.module_from_spec()`. Consulte la sección Ejemplos de la documentación `importlib` para obtener más información sobre los distintos enfoques.

imp.new_module(name)

  Retorna un nuevo objeto de módulo vacío denominado name. Este objeto es not insertado en `sys.modules`.

  Obsoleto desde la versión 3.4: Utilice `importlib.util.module_from_spec()` en su lugar.

imp.reload(module)

  Vuelva a cargar un módulo importado anteriormente. El argumento debe ser un objeto module, por lo que debe haberse importado correctamente antes. Esto es útil si ha editado el archivo de origen del módulo utilizando un editor externo y desea probar la nueva versión sin salir del intérprete de Python. El valor retornado es el objeto module (el mismo que el argumento module).

  Cuando se ejecuta `reload(module)`:

  - El código de los módulos de Python se vuelve a compilar y se vuelve a ejecutar el código de nivel de módulo, definiendo un nuevo conjunto de objetos que están enlazados a nombres en el diccionario del módulo. La función `init` de los módulos de extensión no se llama una segunda vez.

  - Al igual que con todos los demás objetos de Python, los objetos antiguos solo se recuperan después de que sus recuentos de referencia caigan a cero.

  - Los nombres del espacio de nombres del módulo se actualizan para que apunten a cualquier objeto nuevo o modificado.

  - Otras referencias a los objetos antiguos (como nombres externos al módulo) no se rebotan para hacer referencia a los nuevos objetos y deben actualizarse en cada espacio de nombres donde se producen si se desea.

  Hay una serie de otras advertencias:

  Cuando se vuelve a cargar un módulo, se conserva su diccionario (que contiene las variables globales del módulo). Las redefiniciones de nombres invalidarán las definiciones antiguas, por lo que esto generalmente no es un problema. Si la nueva versión de un módulo no define un nombre previamente definido, la definición anterior permanece. Esta característica se puede utilizar en beneficio del módulo si mantiene una tabla global o caché de objetos — con una instrucción `try` puede probar la presencia de la tabla y omitir su inicialización si se desea:

      try:
          cache
      except NameError:
          cache = {}

  Es legal, aunque generalmente no es muy útil para recargar módulos incorporados o cargados dinámicamente, excepto para `sys`, `__main__` y `builtins`. En muchos casos, sin embargo, los módulos de extensión no están diseñados para inicializarse más de una vez y pueden fallar de forma arbitraria cuando se vuelven a cargar.

  Si un módulo importa objetos de otro módulo utilizando `from`… `import` …, llamando a `reload()` para el otro módulo no redefine los objetos importados de él — de una manera alrededor de esto es volver a ejecutar la sentencia `from`, otra es usar `import` y nombres calificados (module.*name*) en su lugar.

  Si un módulo crea instancias de una clase, volver a cargar el módulo que define la clase no afecta a las definiciones de método de las instancias — siguen utilizando la definición de clase antigua. Lo mismo es cierto para las clases derivadas.

  Distinto en la versión 3.3: Se basa en que tanto `__name__` como `__loader__` que se definen en el módulo que se está recargando en lugar de simplemente `__name__`.

  Obsoleto desde la versión 3.4: Utilice `importlib.reload()` en su lugar.

Las siguientes funciones son comodidades para controlar las rutas de acceso de archivo PEP 3147 compiladas en bytes.

Nuevo en la versión 3.2.

imp.cache_from_source(path, debug_override=None)

  Retorna la ruta de acceso PEP 3147 al archivo compilado por bytes asociado con la ruta path de origen. Por ejemplo, si path es `/foo/bar/baz.py` el valor retornado sería `/foo/bar/__pycache__/baz.cpython-32.pyc` para Python 3.2. La cadena `cpython-32` proviene de la etiqueta mágica actual (consulte `get_tag()`; si `sys.implementation.cache_tag` no está definida entonces `NotImplementedError` se generará). Al pasar `True` o `False` para debug_override puede reemplazar el valor del sistema para `__debug__`, lo que da lugar a un código de bytes optimizado.

  ruta no necesita existir.

  Distinto en la versión 3.3: Lanza `NotImplementedError` cuando no se define `sys.implementation.cache_tag`.

  Obsoleto desde la versión 3.4: Utilice `importlib.util.source_from_cache()` en su lugar.

  Distinto en la versión 3.5: El parámetro debug_override ya no crea un archivo `.pyo`.

imp.source_from_cache(path)

  Dada la ruta path a un nombre de archivo PEP 3147, retorne la ruta de acceso del archivo de código fuente asociada. Por ejemplo, si path es `/foo/bar/__pycache__/baz.cpython-32.pyc` la ruta retornada sería `/foo/bar/baz.py`. path no necesita existir, sin embargo, si no se ajusta al formato PEP 3147, se genera un `ValueError`. Si `sys.implementation.cache_tag` no está definido, se genera `NotImplementedError`.

  Distinto en la versión 3.3: Provoca `NotImplementedError` cuando no se define `sys.implementation.cache_tag`.

  Obsoleto desde la versión 3.4: Utilice `importlib.util.source_from_cache()` en su lugar.

imp.get_tag()

  Retorna la cadena de etiqueta mágica PEP 3147 que coincida con esta versión del número mágico de Python, como lo retorna `get_magic()`.

  Obsoleto desde la versión 3.4: Utilice `sys.implementation.cache_tag` directamente a partir de Python 3.3.

Las siguientes funciones ayudan a interactuar con el mecanismo de bloqueo interno del sistema de importación. La semántica de bloqueo de las importaciones es un detalle de implementación que puede variar de una versión a una. Sin embargo, Python garantiza que las importaciones circulares funcionen sin interbloqueos.

imp.lock_held()

  Retorna `True` si el bloqueo de importación global está actualmente retenido, de lo contrario, `False`. En plataformas sin hilos, siempre retorna `False`.

  En plataformas con subprocesos, un subproceso que ejecuta una importación primero contiene un bloqueo de importación global y, a continuación, configura un bloqueo por módulo para el resto de la importación. Esto impide que otros subprocesos importen el mismo módulo hasta que se complete la importación original, lo que impide que otros subprocesos vean objetos de módulo incompletos construidos por el subproceso original. Se hace una excepción para las importaciones circulares, que por construcción tienen que exponer un objeto de módulo incompleto en algún momento.

  Distinto en la versión 3.3: El esquema de bloqueo ha cambiado a bloqueos por módulo en su mayor parte. Se mantiene un bloqueo de importación global para algunas tareas críticas, como la inicialización de los bloqueos por módulo.

  Obsoleto desde la versión 3.4.

imp.acquire_lock()

  Adquiera el bloqueo de importación global del intérprete para el subproceso actual. Este bloqueo debe ser utilizado por los ganchos de importación para garantizar la seguridad de subprocesos al importar módulos.

  Una vez que un subproceso ha adquirido el bloqueo de importación, el mismo subproceso puede adquirirlo de nuevo sin bloquear; el subproceso debe liberarlo una vez por cada vez que lo ha adquirido.

  En plataformas sin subprocesos, esta función no hace nada.

  Distinto en la versión 3.3: El esquema de bloqueo ha cambiado a bloqueos por módulo en su mayor parte. Se mantiene un bloqueo de importación global para algunas tareas críticas, como la inicialización de los bloqueos por módulo.

  Obsoleto desde la versión 3.4.

imp.release_lock()

  Suelte el bloqueo de importación global del intérprete. En plataformas sin subprocesos, esta función no hace nada.

  Distinto en la versión 3.3: El esquema de bloqueo ha cambiado a bloqueos por módulo en su mayor parte. Se mantiene un bloqueo de importación global para algunas tareas críticas, como la inicialización de los bloqueos por módulo.

  Obsoleto desde la versión 3.4.

Las siguientes constantes con valores enteros, definidas en este módulo, se utilizan para indicar el resultado de búsqueda de `find_module()`.

imp.PY_SOURCE

  El módulo se encontró como un archivo de origen.

  Obsoleto desde la versión 3.3.

imp.PY_COMPILED

  El módulo se encontró como un archivo de objeto de código compilado.

  Obsoleto desde la versión 3.3.

imp.C_EXTENSION

  El módulo se encontró como biblioteca compartida cargable dinámicamente.

  Obsoleto desde la versión 3.3.

imp.PKG_DIRECTORY

  El módulo se encontró como un directorio de paquetes.

  Obsoleto desde la versión 3.3.

imp.C_BUILTIN

  El módulo fue encontrado como un módulo incorporado.

  Obsoleto desde la versión 3.3.

imp.PY_FROZEN

  El módulo fue encontrado como un módulo congelado.

  Obsoleto desde la versión 3.3.

class imp.NullImporter(path_string)

  El tipo `NullImporter` es un enlace de importación PEP 302 que controla cadenas de ruta de acceso que no son de directorio al no encontrar ningún módulo. Llamar a este tipo con un directorio existente o una cadena vacía genera `ImportError`. De lo contrario, se retorna una instancia `NullImporter`.

  Las instancias solo tienen un método:

  find_module(fullname[, path])

    Este método siempre retorna `None`, lo que indica que no se pudo encontrar el módulo solicitado.

  Distinto en la versión 3.3: `None` se inserta en `sys.path_importer_cache` en lugar de una instancia de `NullImporter`.

  Obsoleto desde la versión 3.4: Inserte `None` en `sys.path_importer_cache` en su lugar.

## Ejemplos

La siguiente función emula lo que era la instrucción de importación estándar hasta Python 1.4 (sin nombres de módulo jerárquico). (Esta implementación no funcionaría en esa versión, ya que `find_module()` se ha ampliado y `load_module()` se ha añadido en 1.4.)

    import imp
    import sys

    def __import__(name, globals=None, locals=None, fromlist=None):
        # Fast path: see if the module has already been imported.
        try:
            return sys.modules[name]
        except KeyError:
            pass

        # If any of the following calls raises an exception,
        # there's a problem we can't handle -- let the caller handle it.

        fp, pathname, description = imp.find_module(name)

        try:
            return imp.load_module(name, fp, pathname, description)
        finally:
            # Since we may exit via an exception, close fp explicitly.
            if fp:
                fp.close()