Ir al contenido

Módulos

La clase ReflectionModule es una utilidad avanzada de introspección diseñada para analizar módulos de Python en tiempo de ejecución. Proporciona una API completa para inspeccionar clases, funciones, constantes e importaciones definidas en cualquier módulo importable del ecosistema Orionis.

A diferencia de las demás clases de reflexión que operan sobre clases o instancias, ReflectionModule trabaja a nivel de módulo, permitiendo descubrir y manipular los componentes internos de cualquier paquete o archivo Python. Esto la convierte en una herramienta esencial para la carga dinámica de servicios, el descubrimiento automático de clases y la inspección de la estructura interna del framework.

from orionis.services.introspection.modules.reflection import ReflectionModule

La clase ReflectionModule recibe como parámetro el nombre completo del módulo a inspeccionar (como cadena de texto). El módulo se importa automáticamente durante la inicialización. Si el nombre no es una cadena válida o el módulo no puede importarse, se lanzará un TypeError.

from orionis.services.introspection.modules.reflection import ReflectionModule
reflection = ReflectionModule("orionis.services.introspection.modules.reflection")

Si intentas pasar un valor no válido:

# TypeError: no es una cadena
ReflectionModule(123)
# TypeError: cadena vacía
ReflectionModule("")
# TypeError: módulo inexistente
ReflectionModule("modulo.que.no.existe")

La clase ReflectionModule implementa el contrato IReflectionModule, que define la interfaz completa para la introspección de módulos:

from orionis.services.introspection.modules.contracts.reflection import IReflectionModule

Retorna el objeto módulo importado durante la inicialización.

mod = reflection.getModule()
# <module 'orionis.services.introspection.modules.reflection' from '...'>

ReflectionModule ofrece un conjunto completo de métodos para descubrir, consultar, registrar y eliminar clases dentro del módulo reflejado. Todas las clases son detectadas como objetos que heredan de object.

Retorna un diccionario con todas las clases definidas en el módulo, organizadas por nombre.

classes = reflection.getClasses()
# {"ReflectionModule": <class 'ReflectionModule'>, ...}

Retorna únicamente las clases cuyo nombre no comienza con guion bajo (_).

public = reflection.getPublicClasses()
# {"ReflectionModule": <class 'ReflectionModule'>}

Retorna las clases cuyo nombre comienza con un solo guion bajo (_) pero no con doble guion bajo.

protected = reflection.getProtectedClasses()
# {"_InternalHelper": <class '_InternalHelper'>}

Retorna las clases cuyo nombre comienza con doble guion bajo (__) y no termina con doble guion bajo.

private = reflection.getPrivateClasses()
# {"__SecretClass": <class '__SecretClass'>}

Verifica si existe una clase con el nombre especificado dentro del módulo.

reflection.hasClass("ReflectionModule")
# True
reflection.hasClass("ClaseInexistente")
# False

Obtiene una clase por su nombre. Retorna None si no existe.

cls = reflection.getClass("ReflectionModule")
# <class 'ReflectionModule'>
cls = reflection.getClass("NoExiste")
# None

Registra dinámicamente una nueva clase en el módulo. Valida que el nombre sea un identificador válido y que no sea una palabra reservada de Python. El valor debe ser un tipo (type).

class CustomService:
pass
reflection.setClass("CustomService", CustomService)
# True

Si los argumentos no son válidos:

# TypeError: no es un tipo
reflection.setClass("nombre", "no es una clase")
# ValueError: identificador inválido
reflection.setClass("123invalid", CustomService)
# ValueError: palabra reservada
reflection.setClass("class", CustomService)

Elimina una clase del módulo por su nombre. Lanza ValueError si la clase no existe.

reflection.removeClass("CustomService")
# True
# ValueError: clase inexistente
reflection.removeClass("NoExiste")

Las constantes se identifican como atributos del módulo cuyo nombre está en mayúsculas (UPPER_CASE), no son invocables y no son palabras reservadas de Python.

Retorna un diccionario con todas las constantes definidas en el módulo.

constants = reflection.getConstants()
# {"MAX_RETRIES": 3, "DEFAULT_TIMEOUT": 30}

Retorna constantes cuyo nombre no comienza con guion bajo.

public_const = reflection.getPublicConstants()
# {"MAX_RETRIES": 3, "DEFAULT_TIMEOUT": 30}

Retorna constantes cuyo nombre comienza con un solo guion bajo.

protected_const = reflection.getProtectedConstants()
# {"_INTERNAL_LIMIT": 100}

Retorna constantes cuyo nombre comienza con doble guion bajo y no termina con doble guion bajo.

private_const = reflection.getPrivateConstants()
# {"__SECRET_KEY": "abc123"}

Obtiene el valor de una constante específica por nombre. Retorna None si no existe.

value = reflection.getConstant("MAX_RETRIES")
# 3
value = reflection.getConstant("NO_EXISTE")
# None

ReflectionModule permite descubrir y clasificar todas las funciones definidas en el módulo, organizándolas por visibilidad (pública, protegida, privada) y naturaleza (síncrona, asíncrona).

Las funciones se detectan como atributos invocables que poseen el atributo __code__, lo que excluye clases y otros objetos callable.

MétodoDescripción
getFunctions()Todas las funciones del módulo
getPublicFunctions()Funciones públicas (sin prefijo _)
getPublicSyncFunctions()Funciones públicas síncronas
getPublicAsyncFunctions()Funciones públicas asíncronas
getProtectedFunctions()Funciones protegidas (prefijo _)
getProtectedSyncFunctions()Funciones protegidas síncronas
getProtectedAsyncFunctions()Funciones protegidas asíncronas
getPrivateFunctions()Funciones privadas (prefijo __)
getPrivateSyncFunctions()Funciones privadas síncronas
getPrivateAsyncFunctions()Funciones privadas asíncronas

Cada método retorna un diccionario dict[str, callable] donde las claves son los nombres de las funciones y los valores son los objetos función correspondientes.

# Obtener todas las funciones públicas
public_fns = reflection.getPublicFunctions()
# {"process_request": <function>, "validate_input": <function>}
# Filtrar solo funciones públicas asíncronas
async_fns = reflection.getPublicAsyncFunctions()
# {"process_request": <function>}
# Obtener funciones protegidas síncronas
protected_sync = reflection.getProtectedSyncFunctions()
# {"_internal_helper": <function>}

Las funciones se clasifican según las convenciones de nomenclatura de Python:

  • Públicas: nombre sin prefijo de guion bajo
  • Protegidas: nombre con prefijo _ (un guion bajo), sin prefijo __
  • Privadas: nombre con prefijo __ (doble guion bajo), sin sufijo __

La distinción síncrona/asíncrona se determina mediante inspect.iscoroutinefunction().

Retorna un diccionario con los módulos importados detectados a nivel del módulo. Solo identifica atributos cuyo tipo sea ModuleType.

imports = reflection.getImports()
# {"os": <module 'os'>, "sys": <module 'sys'>}

Retorna la ruta absoluta del archivo donde está definido el módulo.

path = reflection.getFile()
# "/path/to/orionis/services/introspection/modules/reflection.py"

Retorna el código fuente completo del módulo como cadena de texto. Lanza ValueError si el archivo no puede leerse.

source = reflection.getSourceCode()
# "from __future__ import annotations\nimport importlib\n..."

ReflectionModule implementa un sistema de caché interno que almacena los resultados de los métodos de descubrimiento. Esto optimiza el rendimiento en llamadas repetidas. La caché se invalida automáticamente al modificar clases con setClass() o removeClass().

Elimina todas las entradas almacenadas en la caché, forzando una recomputación completa en las siguientes llamadas.

reflection.clearCache()

La clase también expone el protocolo de caché mediante los métodos mágicos __getitem__, __setitem__, __contains__ y __delitem__, aunque estos están destinados al uso interno del sistema de reflexión.