ReflectionAbstract
ReflectionAbstract inspecciona una clase sin crear una instancia. Permite construir catálogos de acciones, verificar convenciones y consultar firmas para herramientas de desarrollo. También puede modificar datos y eliminar métodos de la clase original.
Los ejemplos siguientes forman un recorrido ejecutable: guarda el bloque inicial y los fragmentos posteriores, en orden, en un archivo .py. La recuperación de código fuente necesita ese archivo; una clase creada en la consola interactiva puede no tener fuente recuperable.
Construcción y caso de ejemplo
Sección titulada «Construcción y caso de ejemplo»__init__(self, abstract: type) -> Noneabstract es obligatorio y debe satisfacer inspect.isabstract(): heredar de ABC sin métodos abstractos pendientes no basta. Una clase no abstracta produce TypeError; una entrada incorrecta sin __name__ también puede producir AttributeError al construir el mensaje de error. No intenta instanciar el contrato.
from abc import ABC, abstractmethodfrom orionis.introspection import ReflectionAbstract
class Parent: inherited = "base"
def inheritedMethod(self) -> str: return "base"
class ReportContract(Parent, ABC): """Report endpoint metadata."""
format: str = "json" _label: str = "reports" __token: str = "secret" __feature__ = "reports" declared_only: str
def __init__(self, limit: int = 10) -> None: self.instance_only = limit
@abstractmethod def render(self, item_id: int, mode: str = "brief") -> str: return f"{item_id}:{mode}"
def summary(self) -> str: return "summary"
async def fetch(self) -> str: return "data"
def _check(self) -> bool: return True
async def _fetch(self) -> str: return "data"
def __sign(self) -> str: return "signature"
async def __fetch(self) -> str: return "data"
@staticmethod def normalize() -> str: return "json"
@staticmethod async def normalizeAsync() -> str: return "json"
@classmethod def build(cls) -> str: return cls.__name__
@classmethod async def buildAsync(cls) -> str: return cls.__name__
@staticmethod def _normalize() -> str: return "json"
@staticmethod async def _normalizeAsync() -> str: return "json"
@classmethod def _build(cls) -> str: return cls.__name__
@classmethod async def _buildAsync(cls) -> str: return cls.__name__
@staticmethod def __normalize() -> str: return "json"
@staticmethod async def __normalizeAsync() -> str: return "json"
@classmethod def __build(cls) -> str: return cls.__name__
@classmethod async def __buildAsync(cls) -> str: return cls.__name__
@property def title(self) -> str: """Report title.""" return self.format
@property def _title(self) -> str: """Report title.""" return self.format
@property def __title(self) -> str: """Report title.""" return self.format
def __repr__(self) -> str: return "Report"
r = ReflectionAbstract(ReportContract)Importa desde orionis.introspection; también existe la ruta directa orionis.introspection.abstract.reflection. Los métodos de consulta son síncronos, aunque los miembros inspeccionados puedan ser async.
Alcance de la clasificación
Sección titulada «Alcance de la clasificación»El escaneo recorre solo Clase.__dict__, no la MRO. Los getters de colecciones excluyen miembros heredados; getBaseClasses() permite visitar las bases explícitamente. Un campo creado con self.campo no es un dato de clase, y una anotación sin valor no aparece entre los atributos.
La separación distingue datos, property, staticmethod, classmethod y otros callables. No comprueba que todo callable sea una función de instancia convencional. Para decidir async utiliza inspect.iscoroutinefunction(), no ejecuta el miembro: un generador asíncrono o una función síncrona que devuelve un awaitable no se convierten por eso en corrutinas.
Los nombres públicos no comienzan con _; los protegidos usan _; los privados se reconocen por el prefijo de mangling de la clase y se presentan como __nombre. Los dunder terminan también en __ y se consultan aparte. La normalización reproduce el prefijo que Python genera al quitar los _ iniciales del nombre de la clase.
Usa nombres privados tal como están escritos en el código ("__sign"), no "_ReportContract__sign". La clasificación compara prefijos, no aplica un control de acceso ni impide usar un miembro privado.
Identidad, documentación y fuente
Sección titulada «Identidad, documentación y fuente»getClass
getClass(self) -> typeDevuelve el objeto de clase original (type), sin construirlo.
assert r.getClass() is ReportContractgetClassName
getClassName(self) -> strDevuelve el __name__ capturado al construir el wrapper como str, no __qualname__. clearCache() no vuelve a capturarlo.
assert r.getClassName() == "ReportContract"getModuleName
getModuleName(self) -> strDevuelve el nombre del módulo capturado al construir el wrapper como str. clearCache() no vuelve a capturarlo.
assert r.getModuleName() == ReportContract.__module__getModuleWithClassName
getModuleWithClassName(self) -> strDevuelve modulo.NombreClase como str, con los nombres capturados al construir el wrapper. No agrega los ámbitos de una clase anidada.
assert r.getModuleWithClassName() == f"{ReportContract.__module__}.ReportContract"getDocstring
getDocstring(self) -> str | NoneDevuelve __doc__ o None; no aplica limpieza ni hereda la documentación de otra clase.
assert r.getDocstring() == "Report endpoint metadata."getBaseClasses
getBaseClasses(self) -> list[type]Devuelve una lista de bases directas (type); no recorre la MRO completa.
assert Parent in r.getBaseClasses()getSourceCode
getSourceCode(self) -> strNo recibe argumentos. Devuelve el código de toda la clase como str, mediante inspect.getsource(). Convierte OSError y TypeError en ValueError cuando no puede recuperarlo. No permite seleccionar un método.
assert "class ReportContract" in r.getSourceCode()getFile
getFile(self) -> strDevuelve la ruta del archivo de la clase como str. Convierte el TypeError de inspect.getfile() en ValueError; no garantiza que el archivo siga existiendo.
assert r.getFile().endswith(".py")getAnnotations
getAnnotations(self) -> dictDevuelve un dict de anotaciones de la clase, incluso campos anotados sin valor. Quita el prefijo de clase de los nombres privados y no analiza las anotaciones de métodos.
assert "declared_only" in r.getAnnotations()assert "__token" in r.getAnnotations()Datos de clase
Sección titulada «Datos de clase»hasAttribute
hasAttribute(self, attribute: str) -> boolattribute es el nombre obligatorio de un dato declarado en la clase. Devuelve bool; no incluye métodos, propiedades, miembros heredados ni valores creados únicamente por el constructor.
assert r.hasAttribute("format")assert not r.hasAttribute("declared_only")assert not r.hasAttribute("inherited")assert not r.hasAttribute("instance_only")getAttribute
getAttribute(self, attribute: str) -> object | Noneattribute es obligatorio. Busca únicamente en el diccionario de datos clasificados y devuelve el valor, o None si falta. No admite argumento default. Usa hasAttribute() para distinguir un valor None de un dato inexistente.
assert r.getAttribute("format") == "json"assert r.getAttribute("missing") is Noneassert r.getAttribute("inherited") is NonegetAttributes
getAttributes(self) -> dictDevuelve un dict con datos públicos, protegidos, privados normalizados y dunder no excluidos, en ese orden de combinación. No contiene campos de instancias ni anotaciones sin valor.
attributes = r.getAttributes()assert attributes["format"] == "json"assert attributes["__token"] == "secret"getPublicAttributes
getPublicAttributes(self) -> dictDevuelve un dict de datos cuyos nombres no comienzan con _.
assert r.getPublicAttributes()["format"] == "json"getProtectedAttributes
getProtectedAttributes(self) -> dictDevuelve un dict de datos con _ inicial que no son privados ni dunder.
assert r.getProtectedAttributes()["_label"] == "reports"getPrivateAttributes
getPrivateAttributes(self) -> dictDevuelve un dict de datos privados. Sus claves conservan __ pero omiten el prefijo de clase que introduce Python.
assert r.getPrivateAttributes()["__token"] == "secret"getDunderAttributes
getDunderAttributes(self) -> dictDevuelve un dict de datos __nombre__ personalizados. La implementación excluye metadatos de Python como __dict__, __module__, __doc__ y __annotations__.
assert r.getDunderAttributes()["__feature__"] == "reports"assert "__module__" not in r.getDunderAttributes()getMagicAttributes
getMagicAttributes(self) -> dictAlias de getDunderAttributes(); devuelve el mismo diccionario almacenado.
assert r.getMagicAttributes() is r.getDunderAttributes()setAttribute
setAttribute(self, name: str, value: object) -> boolname debe ser un identificador Python válido que no sea palabra reservada (ValueError en caso contrario). value es obligatorio y no puede ser callable (TypeError). Modifica la clase original y devuelve True; admite __privados. No valida anotaciones ni actualiza __abstractmethods__.
assert r.setAttribute("extra_label", "export") is Trueassert ReportContract.extra_label == "export"assert r.removeAttribute("extra_label") is TrueremoveAttribute
removeAttribute(self, name: str) -> boolname identifica un dato propio, usando su nombre original si es privado. Elimina el atributo real y devuelve True. Si no está en la clasificación de datos, lanza ValueError; las restricciones del metatipo pueden propagarse.
r.setAttribute("__temporary", 20)assert r.removeAttribute("__temporary") is Trueassert not r.hasAttribute("__temporary")Aunque el error de setAttribute() para callables menciona setMethod, ReflectionAbstract no implementa setMethod(). No hay un método de este wrapper para añadir funciones.
Métodos de instancia
Sección titulada «Métodos de instancia»getMethods
getMethods(self) -> list[str]Devuelve list[str]: métodos de instancia, de clase y estáticos, cada categoría ordenada por visibilidad pública, protegida y privada. Excluye propiedades y dunder; no ordena alfabéticamente.
methods = r.getMethods()assert "render" in methods and "build" in methods and "normalize" in methodsassert "title" not in methods and "__repr__" not in methodsgetPublicMethods
getPublicMethods(self) -> list[str]Devuelve list[str] de métodos de instancia públicos, incluyendo síncronos y asíncronos. No ejecuta los métodos. No recibe argumentos.
assert "summary" in r.getPublicMethods()getPublicSyncMethods
getPublicSyncMethods(self) -> list[str]Devuelve list[str] de métodos de instancia públicos que no son funciones de corrutina. No ejecuta los métodos. No recibe argumentos.
assert "summary" in r.getPublicSyncMethods()assert "fetch" not in r.getPublicSyncMethods()getPublicAsyncMethods
getPublicAsyncMethods(self) -> list[str]Devuelve list[str] de métodos de instancia públicos que cumplen inspect.iscoroutinefunction(). No ejecuta los métodos. No recibe argumentos.
assert "fetch" in r.getPublicAsyncMethods()assert "summary" not in r.getPublicAsyncMethods()getProtectedMethods
getProtectedMethods(self) -> list[str]Devuelve list[str] de métodos de instancia protegidos, incluyendo síncronos y asíncronos. No ejecuta los métodos. No recibe argumentos.
assert "_check" in r.getProtectedMethods()getProtectedSyncMethods
getProtectedSyncMethods(self) -> list[str]Devuelve list[str] de métodos de instancia protegidos que no son funciones de corrutina. No ejecuta los métodos. No recibe argumentos.
assert "_check" in r.getProtectedSyncMethods()assert "_fetch" not in r.getProtectedSyncMethods()getProtectedAsyncMethods
getProtectedAsyncMethods(self) -> list[str]Devuelve list[str] de métodos de instancia protegidos que cumplen inspect.iscoroutinefunction(). No ejecuta los métodos. No recibe argumentos.
assert "_fetch" in r.getProtectedAsyncMethods()assert "_check" not in r.getProtectedAsyncMethods()getPrivateMethods
getPrivateMethods(self) -> list[str]Devuelve list[str] de métodos de instancia privados, incluyendo síncronos y asíncronos. Los resultados usan __nombre, sin el prefijo de clase. No ejecuta los métodos. No recibe argumentos.
assert "__sign" in r.getPrivateMethods()getPrivateSyncMethods
getPrivateSyncMethods(self) -> list[str]Devuelve list[str] de métodos de instancia privados que no son funciones de corrutina. Los resultados usan __nombre, sin el prefijo de clase. No ejecuta los métodos. No recibe argumentos.
assert "__sign" in r.getPrivateSyncMethods()assert "__fetch" not in r.getPrivateSyncMethods()getPrivateAsyncMethods
getPrivateAsyncMethods(self) -> list[str]Devuelve list[str] de métodos de instancia privados que cumplen inspect.iscoroutinefunction(). Los resultados usan __nombre, sin el prefijo de clase. No ejecuta los métodos. No recibe argumentos.
assert "__fetch" in r.getPrivateAsyncMethods()assert "__sign" not in r.getPrivateAsyncMethods()Métodos de clase
Sección titulada «Métodos de clase»getPublicClassMethods
getPublicClassMethods(self) -> list[str]Devuelve list[str] de métodos de clase (@classmethod) públicos, incluyendo síncronos y asíncronos. No ejecuta los métodos. No recibe argumentos.
assert "build" in r.getPublicClassMethods()getPublicClassSyncMethods
getPublicClassSyncMethods(self) -> list[str]Devuelve list[str] de métodos de clase (@classmethod) públicos que no son funciones de corrutina. No ejecuta los métodos. No recibe argumentos.
assert "build" in r.getPublicClassSyncMethods()assert "buildAsync" not in r.getPublicClassSyncMethods()getPublicClassAsyncMethods
getPublicClassAsyncMethods(self) -> list[str]Devuelve list[str] de métodos de clase (@classmethod) públicos que cumplen inspect.iscoroutinefunction(). No ejecuta los métodos. No recibe argumentos.
assert "buildAsync" in r.getPublicClassAsyncMethods()assert "build" not in r.getPublicClassAsyncMethods()getProtectedClassMethods
getProtectedClassMethods(self) -> list[str]Devuelve list[str] de métodos de clase (@classmethod) protegidos, incluyendo síncronos y asíncronos. No ejecuta los métodos. No recibe argumentos.
assert "_build" in r.getProtectedClassMethods()getProtectedClassSyncMethods
getProtectedClassSyncMethods(self) -> list[str]Devuelve list[str] de métodos de clase (@classmethod) protegidos que no son funciones de corrutina. No ejecuta los métodos. No recibe argumentos.
assert "_build" in r.getProtectedClassSyncMethods()assert "_buildAsync" not in r.getProtectedClassSyncMethods()getProtectedClassAsyncMethods
getProtectedClassAsyncMethods(self) -> list[str]Devuelve list[str] de métodos de clase (@classmethod) protegidos que cumplen inspect.iscoroutinefunction(). No ejecuta los métodos. No recibe argumentos.
assert "_buildAsync" in r.getProtectedClassAsyncMethods()assert "_build" not in r.getProtectedClassAsyncMethods()getPrivateClassMethods
getPrivateClassMethods(self) -> list[str]Devuelve list[str] de métodos de clase (@classmethod) privados, incluyendo síncronos y asíncronos. Los resultados usan __nombre, sin el prefijo de clase. No ejecuta los métodos. No recibe argumentos.
assert "__build" in r.getPrivateClassMethods()getPrivateClassSyncMethods
getPrivateClassSyncMethods(self) -> list[str]Devuelve list[str] de métodos de clase (@classmethod) privados que no son funciones de corrutina. Los resultados usan __nombre, sin el prefijo de clase. No ejecuta los métodos. No recibe argumentos.
assert "__build" in r.getPrivateClassSyncMethods()assert "__buildAsync" not in r.getPrivateClassSyncMethods()getPrivateClassAsyncMethods
getPrivateClassAsyncMethods(self) -> list[str]Devuelve list[str] de métodos de clase (@classmethod) privados que cumplen inspect.iscoroutinefunction(). Los resultados usan __nombre, sin el prefijo de clase. No ejecuta los métodos. No recibe argumentos.
assert "__buildAsync" in r.getPrivateClassAsyncMethods()assert "__build" not in r.getPrivateClassAsyncMethods()Métodos estáticos
Sección titulada «Métodos estáticos»getPublicStaticMethods
getPublicStaticMethods(self) -> list[str]Devuelve list[str] de métodos estáticos (@staticmethod) públicos, incluyendo síncronos y asíncronos. No ejecuta los métodos. No recibe argumentos.
assert "normalize" in r.getPublicStaticMethods()getPublicStaticSyncMethods
getPublicStaticSyncMethods(self) -> list[str]Devuelve list[str] de métodos estáticos (@staticmethod) públicos que no son funciones de corrutina. No ejecuta los métodos. No recibe argumentos.
assert "normalize" in r.getPublicStaticSyncMethods()assert "normalizeAsync" not in r.getPublicStaticSyncMethods()getPublicStaticAsyncMethods
getPublicStaticAsyncMethods(self) -> list[str]Devuelve list[str] de métodos estáticos (@staticmethod) públicos que cumplen inspect.iscoroutinefunction(). No ejecuta los métodos. No recibe argumentos.
assert "normalizeAsync" in r.getPublicStaticAsyncMethods()assert "normalize" not in r.getPublicStaticAsyncMethods()getProtectedStaticMethods
getProtectedStaticMethods(self) -> list[str]Devuelve list[str] de métodos estáticos (@staticmethod) protegidos, incluyendo síncronos y asíncronos. No ejecuta los métodos. No recibe argumentos.
assert "_normalize" in r.getProtectedStaticMethods()getProtectedStaticSyncMethods
getProtectedStaticSyncMethods(self) -> list[str]Devuelve list[str] de métodos estáticos (@staticmethod) protegidos que no son funciones de corrutina. No ejecuta los métodos. No recibe argumentos.
assert "_normalize" in r.getProtectedStaticSyncMethods()assert "_normalizeAsync" not in r.getProtectedStaticSyncMethods()getProtectedStaticAsyncMethods
getProtectedStaticAsyncMethods(self) -> list[str]Devuelve list[str] de métodos estáticos (@staticmethod) protegidos que cumplen inspect.iscoroutinefunction(). No ejecuta los métodos. No recibe argumentos.
assert "_normalizeAsync" in r.getProtectedStaticAsyncMethods()assert "_normalize" not in r.getProtectedStaticAsyncMethods()getPrivateStaticMethods
getPrivateStaticMethods(self) -> list[str]Devuelve list[str] de métodos estáticos (@staticmethod) privados, incluyendo síncronos y asíncronos. Los resultados usan __nombre, sin el prefijo de clase. No ejecuta los métodos. No recibe argumentos.
assert "__normalize" in r.getPrivateStaticMethods()getPrivateStaticSyncMethods
getPrivateStaticSyncMethods(self) -> list[str]Devuelve list[str] de métodos estáticos (@staticmethod) privados que no son funciones de corrutina. Los resultados usan __nombre, sin el prefijo de clase. No ejecuta los métodos. No recibe argumentos.
assert "__normalize" in r.getPrivateStaticSyncMethods()assert "__normalizeAsync" not in r.getPrivateStaticSyncMethods()getPrivateStaticAsyncMethods
getPrivateStaticAsyncMethods(self) -> list[str]Devuelve list[str] de métodos estáticos (@staticmethod) privados que cumplen inspect.iscoroutinefunction(). Los resultados usan __nombre, sin el prefijo de clase. No ejecuta los métodos. No recibe argumentos.
assert "__normalizeAsync" in r.getPrivateStaticAsyncMethods()assert "__normalize" not in r.getPrivateStaticAsyncMethods()Existencia, cambios y métodos dunder
Sección titulada «Existencia, cambios y métodos dunder»hasMethod
hasMethod(self, name: str) -> boolname es obligatorio; devuelve bool para métodos propios de instancia, clase o estáticos. Usa nombres privados sin mangling. Los dunder se consultan por separado y aquí devuelven False.
assert r.hasMethod("render")assert r.hasMethod("__sign")assert not r.hasMethod("__repr__")assert not r.hasMethod("inheritedMethod")removeMethod
removeMethod(self, name: str) -> boolElimina de la clase el método propio name y devuelve True; si no aparece en hasMethod(), lanza ValueError. Admite privados y descriptores estáticos/de clase. No sirve para borrar dunder ni métodos heredados.
original_summary = ReportContract.__dict__["summary"]assert r.removeMethod("summary") is Trueassert not r.hasMethod("summary")setattr(ReportContract, "summary", original_summary)r.clearCache()getDunderMethods
getDunderMethods(self) -> list[str]Devuelve list[str] de callables propios __nombre__ que no son properties, staticmethods ni classmethods. Incluye __init__ si se declaró en la clase.
assert "__repr__" in r.getDunderMethods()assert "__init__" in r.getDunderMethods()getMagicMethods
getMagicMethods(self) -> list[str]Alias de getDunderMethods(); devuelve la misma lista almacenada.
assert r.getMagicMethods() is r.getDunderMethods()Propiedades sin construir la clase
Sección titulada «Propiedades sin construir la clase»getProperties
getProperties(self) -> list[str]Devuelve list[str] de descriptores property propios. Conserva el orden de declaración, normaliza los privados y no ejecuta los getters.
assert r.getProperties() == ["title", "_title", "__title"]getPublicProperties
getPublicProperties(self) -> list[str]Devuelve list[str] de propiedades públicas.
assert r.getPublicProperties() == ["title"]getProtectedProperties
getProtectedProperties(self) -> list[str]Devuelve list[str] de propiedades protegidas.
assert r.getProtectedProperties() == ["_title"]getPrivateProperties
getPrivateProperties(self) -> list[str]Devuelve list[str] de propiedades privadas usando su nombre original.
assert r.getPrivateProperties() == ["__title"]getPropertySignature
getPropertySignature(self, name: str) -> inspect.Signaturename es obligatorio. Devuelve inspect.Signature del getter fget, incluido self, sin ejecutarlo. Admite privados e incluso propiedades heredadas accesibles por getattr(). Lanza ValueError si falta y TypeError si no es property o no puede inspeccionarse su getter.
assert list(r.getPropertySignature("title").parameters) == ["self"]assert list(r.getPropertySignature("__title").parameters) == ["self"]getPropertyDocstring
getPropertyDocstring(self, name: str) -> str | Nonename es obligatorio. Devuelve str | None con el docstring de fget; sin getter devuelve None. Admite privados y propiedades heredadas. Lanza ValueError si falta y TypeError si el atributo no es property.
assert r.getPropertyDocstring("title") == "Report title."assert r.getPropertyDocstring("__title") == "Report title."Firmas e información para dependencias
Sección titulada «Firmas e información para dependencias»getMethodSignature
getMethodSignature(self, name: str) -> inspect.Signaturename es obligatorio. Devuelve inspect.Signature sin invocar el método: conserva self en métodos de instancia y omite cls al obtener un classmethod ligado. Lanza ValueError si el nombre no está clasificado, TypeError si dejó de ser callable; también pueden propagarse errores de inspección.
signature = r.getMethodSignature("render")assert list(signature.parameters) == ["self", "item_id", "mode"]assert "cls" not in r.getMethodSignature("build").parametersassert "self" not in r.getMethodSignature("normalize").parametersconstructorSignature
constructorSignature(self) -> SignatureDevuelve el Signature de Orionis para las dependencias de __init__, sin construir la clase. Sus mapas resolved, unresolved y ordered contienen Argument. No es inspect.Signature ni resuelve instancias de servicios.
analysis = r.constructorSignature()assert list(analysis.ordered) == ["limit"]assert analysis.resolved["limit"].default == 10methodSignature
methodSignature(self, method_name: str) -> Signaturemethod_name es obligatorio. Devuelve el Signature de dependencias de un método propio; quita self/cls y clasifica sus argumentos sin ejecutarlo. Lanza AttributeError si hasMethod() es falso; los errores del analizador se propagan. Admite privados.
analysis = r.methodSignature("render")assert list(analysis.ordered) == ["item_id", "mode"]assert "item_id" in analysis.unresolvedassert analysis.resolved["mode"].default == "brief"Estos dos últimos métodos delegan en ReflectDependencies. resolved significa que existe información suficiente de tipo o valor predeterminado; no implica que se haya creado o registrado un servicio. El argumento requerido builtin item_id: int permanece sin resolver, mientras que mode="brief" tiene un valor predeterminado conocido.
Caché local y operadores de acceso
Sección titulada «Caché local y operadores de acceso»El primer getter de miembros realiza el escaneo; las listas y diccionarios devueltos son los objetos almacenados, no copias defensivas. No los modifiques para «editar» la clase: eso altera la vista en caché y puede producir resultados incoherentes. Usa los métodos de modificación o crea una copia de la respuesta.
setAttribute(), removeAttribute() y removeMethod() invalidan las clasificaciones de miembros, pero pueden conservar firmas y otros resultados calculados previamente. Tras cambiar firmas, anotaciones o metadatos, ejecuta clearCache(). Los cambios hechos directamente sobre la clase tampoco se detectan automáticamente.
El nombre de clase, el nombre de módulo y el prefijo privado se capturan en el constructor y no cambian con clearCache(). Si modificas __name__ o __module__, crea otro wrapper. El docstring se lee directamente en cada llamada.
Los operadores siguientes acceden a la caché del wrapper, no a los atributos de la clase. Usa claves propias que no coincidan con las internas (attributes, methods, etc.); sobrescribir o borrar claves internas puede romper la consistencia del escaneo.
__setitem__
__setitem__(self, key: str, value: object) -> NoneGuarda value bajo la clave obligatoria key; devuelve None. No modifica la clase.
r["app:note"] = "reviewed"assert r["app:note"] == "reviewed"__getitem__
__getitem__(self, key: str) -> object | NoneDevuelve el valor bajo key o None si no existe; no lanza KeyError. Una clave guardada con None se distingue usando in.
assert r["app:note"] == "reviewed"assert r["app:absent"] is None__contains__
__contains__(self, key: str) -> boolDevuelve bool indicando si key está almacenada, incluso cuando su valor es None.
r["app:empty"] = Noneassert "app:empty" in rassert "app:absent" not in r__delitem__
__delitem__(self, key: str) -> NoneElimina key, devuelve None e ignora claves inexistentes.
del r["app:note"]del r["app:absent"]assert "app:note" not in rclearCache
clearCache(self) -> NoneDevuelve None. Descarta todos los datos almacenados en este wrapper, incluidas las claves añadidas con corchetes. La siguiente consulta vuelve a inspeccionar; no deshace cambios de la clase ni vacía la caché global de dependencias.
r["app:note"] = "cached"assert r.clearCache() is Noneassert "app:note" not in rassert "render" in r.getPublicMethods()Integración con inyección de dependencias
Sección titulada «Integración con inyección de dependencias»El wrapper necesita saber qué clase inspeccionar. No supongas que anotar un parámetro como ReflectionAbstract selecciona automáticamente el contrato o componente de tu aplicación. Construye el reflector cuando conoces la clase, o encapsúlalo en un servicio propio que el contenedor pueda resolver. No existe un binding nativo que elija esa clase por ti.
from orionis.http import JSONResponse
class ReportCatalog: def __init__(self) -> None: self.reflection = ReflectionAbstract(ReportContract)
def actions(self) -> list[str]: return list(self.reflection.getPublicMethods())
class ReportExporter: def __init__(self, catalog: ReportCatalog) -> None: self.catalog = catalog
def actions(self) -> list[str]: return self.catalog.actions()
class MetadataController: async def __call__(self, catalog: ReportCatalog) -> JSONResponse: return JSONResponse({"actions": catalog.actions()})Aquí se inyecta ReportCatalog, un servicio de la aplicación con constructor sin argumentos. El catálogo crea explícitamente el reflector y devuelve una copia de la lista. La inyección en el constructor de otro servicio funciona con la misma anotación catalog: ReportCatalog. El acceso directo sigue siendo válido fuera de controladores. Consulta el contenedor para los registros, ciclos de vida y contratos personalizados.
Errores y límites que conviene conocer
Sección titulada «Errores y límites que conviene conocer»Las consultas no ejecutan acciones ni aplican anotaciones como validación de datos. Los cambios son reales y afectan a todos los usuarios de la clase dentro del proceso; no crean una copia y no se revierten al borrar el reflector. Una operación puede fallar por restricciones de descriptores o metaclases, y esas excepciones se propagan.
No hay separación entre métodos abstractos y concretos en los getters de métodos: ambos aparecen según su visibilidad y descriptor. El wrapper no llama a abc.update_abstractmethods() tras una modificación.
Un nombre que getDunderMethods() devuelve no es válido automáticamente para hasMethod(), removeMethod(), getMethodSignature() ni methodSignature(): esas operaciones usan la lista de métodos no dunder. Las propiedades se consultan mediante sus APIs específicas.
Si cambias funciones dinámicamente, limpiar este wrapper no vacía las cachés compartidas de ReflectDependencies. Las funciones nuevas se analizan por su identidad, pero modificar anotaciones o valores predeterminados de la misma función puede conservar un análisis anterior; revisa la guía de dependencias.