Skip to content

Abstract Classes

The ReflectionAbstract class is an advanced introspection utility designed to analyze Python abstract base classes (ABCs) at runtime. It provides a comprehensive API for inspecting attributes, methods, properties, metadata, and dependencies of any abstract class registered in the Orionis Framework.

This tool is especially useful for building dependency injection systems, generating automatic documentation, validating interface contracts, and performing runtime static analysis.

from orionis.services.introspection.abstract.reflection import ReflectionAbstract

The ReflectionAbstract class receives a valid abstract class that inherits from abc.ABC as its parameter. If the provided class is not abstract, a TypeError will be raised.

from abc import ABC, abstractmethod
from orionis.services.introspection.abstract.reflection import ReflectionAbstract
class MyContract(ABC):
@abstractmethod
def execute(self) -> str:
"""Execute the operation."""
...
reflection = ReflectionAbstract(MyContract)

If you attempt to pass a non-abstract class:

class RegularClass:
pass
# This will raise TypeError:
# "The class 'RegularClass' is not an abstract base class."
reflection = ReflectionAbstract(RegularClass)

The ReflectionAbstract class implements the IReflectionAbstract contract, which defines the complete interface for abstract class introspection:

from orionis.services.introspection.abstract.contracts.reflection import IReflectionAbstract

These methods provide basic identification information about the reflected abstract class.

Returns the type (the class) associated with the reflection instance.

cls = reflection.getClass()
# <class 'MyContract'>

Returns the name of the abstract class as a string.

name = reflection.getClassName()
# "MyContract"

Returns the fully qualified module name where the class is defined.

module = reflection.getModuleName()
# "app.contracts.my_contract"

Returns the full module path along with the class name, separated by a dot.

full_name = reflection.getModuleWithClassName()
# "app.contracts.my_contract.MyContract"

These methods extract descriptive information about the abstract class.

Returns the class docstring, or None if one is not defined.

doc = reflection.getDocstring()
# "Execute the operation." or None

Returns a list of the direct base classes of the abstract class.

bases = reflection.getBaseClasses()
# [<class 'abc.ABC'>]

Retrieves the complete source code of the class as a string. Raises ValueError if it cannot be obtained.

source = reflection.getSourceCode()

Returns the absolute file path where the class is defined. Raises ValueError if it cannot be determined.

file_path = reflection.getFile()
# "/path/to/app/contracts/my_contract.py"

Returns a dictionary with the type annotations of the class attributes. Private attribute names are normalized by removing the name mangling prefix.

from abc import ABC, abstractmethod
class Configurable(ABC):
name: str
__timeout: int
@abstractmethod
def configure(self) -> None:
...
reflection = ReflectionAbstract(Configurable)
annotations = reflection.getAnnotations()
# {"name": <class 'str'>, "__timeout": <class 'int'>}

The class provides a complete set of methods for inspecting and manipulating class-level attributes, organized by visibility level.

Checks whether the class has a specific attribute.

exists = reflection.hasAttribute("my_attr")
# True or False

Gets the value of a class attribute. Returns None if the attribute does not exist.

value = reflection.getAttribute("my_attr")

Sets the value of an attribute on the class. The name must be a valid Python identifier and cannot be a reserved keyword. The value cannot be callable.

reflection.setAttribute("max_retries", 3)
# True

Removes an attribute from the class. Raises ValueError if the attribute does not exist.

reflection.removeAttribute("max_retries")
# True

Returns a dictionary with all class-level attributes, combining public, protected, private, and dunder attributes. Excludes callables, static/class methods, and properties.

all_attrs = reflection.getAttributes()
# {"public_attr": 1, "_protected": 2, "__private": 3, "__custom__": 4}

Returns only public attributes (no underscore prefix).

public = reflection.getPublicAttributes()
# {"public_attr": 1}

Returns protected attributes (single leading underscore, not dunder or private).

protected = reflection.getProtectedAttributes()
# {"_protected": 2}

Returns private attributes (with name mangling). Names are normalized by removing the _ClassName prefix.

private = reflection.getPrivateAttributes()
# {"__private": 3}

Returns custom dunder attributes (double underscores at the beginning and end). Automatically excludes Python built-in dunder attributes such as __class__, __dict__, __module__, etc.

dunder = reflection.getDunderAttributes()
# {"__custom__": 4}

Alias for getDunderAttributes(). Returns the same magic attributes.

magic = reflection.getMagicAttributes()

The method introspection API is one of the most comprehensive features of ReflectionAbstract. It allows querying methods organized by visibility (public, protected, private), type (instance, class, static), and nature (synchronous, asynchronous).

Checks whether the class contains a method with the given name.

exists = reflection.hasMethod("execute")
# True or False

Removes a method from the abstract class. Raises ValueError if the method does not exist.

reflection.removeMethod("execute")
# True

Retrieves the signature (inspect.Signature) of a specific method. Raises ValueError if the method does not exist or is not callable.

import inspect
sig = reflection.getMethodSignature("execute")
# <Signature (self) -> str>

Returns a list with the names of all methods defined in the class, including public, protected, private, class, and static methods.

all_methods = reflection.getMethods()
# ["execute", "validate", "_prepare", "__internal", "from_config", ...]

Returns the names of all public instance methods. Excludes dunder, protected, private, static, class methods, and properties.

public = reflection.getPublicMethods()
# ["execute", "validate"]

Returns only public synchronous methods (not coroutines).

sync = reflection.getPublicSyncMethods()

Returns only public asynchronous methods (coroutine functions).

async_methods = reflection.getPublicAsyncMethods()

Returns protected instance methods (single leading underscore).

protected = reflection.getProtectedMethods()
# ["_prepare", "_validate_input"]

Returns protected synchronous methods.

sync = reflection.getProtectedSyncMethods()

Returns protected asynchronous methods.

async_methods = reflection.getProtectedAsyncMethods()

Returns private instance methods (with name mangling). Names are normalized by removing the _ClassName prefix.

private = reflection.getPrivateMethods()
# ["__internal_process"]

Returns private synchronous methods.

sync = reflection.getPrivateSyncMethods()

Returns private asynchronous methods.

async_methods = reflection.getPrivateAsyncMethods()

Returns public class methods (decorated with @classmethod).

class_methods = reflection.getPublicClassMethods()
# ["from_config"]

Returns public synchronous class methods.

sync = reflection.getPublicClassSyncMethods()

Returns public asynchronous class methods.

async_methods = reflection.getPublicClassAsyncMethods()

Returns protected class methods.

protected = reflection.getProtectedClassMethods()

Returns protected synchronous class methods.

sync = reflection.getProtectedClassSyncMethods()

Returns protected asynchronous class methods.

async_methods = reflection.getProtectedClassAsyncMethods()

Returns private class methods. Names are normalized by removing the name mangling prefix.

private = reflection.getPrivateClassMethods()

Returns private synchronous class methods.

sync = reflection.getPrivateClassSyncMethods()

Returns private asynchronous class methods.

async_methods = reflection.getPrivateClassAsyncMethods()

Returns public static methods (decorated with @staticmethod).

static_methods = reflection.getPublicStaticMethods()
# ["utility_method"]

Returns public synchronous static methods.

sync = reflection.getPublicStaticSyncMethods()

Returns public asynchronous static methods.

async_methods = reflection.getPublicStaticAsyncMethods()

Returns protected static methods.

protected = reflection.getProtectedStaticMethods()

Returns protected synchronous static methods.

sync = reflection.getProtectedStaticSyncMethods()

Returns protected asynchronous static methods.

async_methods = reflection.getProtectedStaticAsyncMethods()

Returns private static methods. Names are normalized by removing the name mangling prefix.

private = reflection.getPrivateStaticMethods()

Returns private synchronous static methods.

sync = reflection.getPrivateStaticSyncMethods()

Returns private asynchronous static methods.

async_methods = reflection.getPrivateStaticAsyncMethods()

Returns all dunder methods (double underscores at the beginning and end) defined in the class. Excludes static methods, class methods, and properties.

dunder = reflection.getDunderMethods()
# ["__init__", "__str__", "__repr__"]

Alias for getDunderMethods().

magic = reflection.getMagicMethods()

Methods for inspecting properties (decorated with @property) defined in the abstract class.

Returns a list with the names of all properties. Private property names are normalized by removing the name mangling prefix.

props = reflection.getProperties()
# ["name", "_status", "__secret"]

Returns public properties (no underscore prefix).

public = reflection.getPublicProperties()
# ["name"]

Returns protected properties (single leading underscore).

protected = reflection.getProtectedProperties()
# ["_status"]

Returns private properties. Names are normalized by removing the _ClassName prefix.

private = reflection.getPrivateProperties()
# ["__secret"]

Retrieves the signature of a property’s getter method. Raises ValueError if the property does not exist.

sig = reflection.getPropertySignature("name")
# <Signature (self) -> str>

Retrieves the docstring of a property’s getter method. Returns None if there is no docstring.

doc = reflection.getPropertyDocstring("name")
# "The name of the entity." or None

These methods analyze constructor and method signatures to determine their dependencies, which is fundamental for the framework’s dependency injection systems.

Returns a Signature object containing the constructor dependencies, including resolved dependencies (with annotated types) and unresolved dependencies (parameters without annotations or default values).

sig = reflection.constructorSignature()
# Signature(resolved=[...], unresolved=[...])

Returns a Signature object with the dependencies of a specific method. Raises AttributeError if the method does not exist.

sig = reflection.methodSignature("execute")
# Signature(resolved=[...], unresolved=[...])

ReflectionAbstract implements an internal cache system to optimize performance. The results of introspection operations are automatically stored and reused in subsequent calls.

The class implements the special methods __getitem__, __setitem__, __contains__, and __delitem__, allowing you to interact with the cache as if it were a dictionary:

# Check if a key exists in the cache
"source_code" in reflection
# Get a cached value
value = reflection["source_code"]
# Set a cache value
reflection["custom_key"] = "custom_value"
# Delete a cache entry
del reflection["custom_key"]

Clears all reflection cache, forcing subsequent calls to recompute results.

reflection.clearCache()
from abc import ABC, abstractmethod
from orionis.services.introspection.abstract.reflection import ReflectionAbstract
class PaymentGateway(ABC):
"""Abstract payment gateway interface."""
gateway_name: str
_timeout: int = 30
__retries: int = 3
@abstractmethod
def process_payment(self, amount: float, currency: str) -> bool:
"""Process a payment transaction."""
...
@abstractmethod
async def refund(self, transaction_id: str) -> bool:
"""Refund a transaction."""
...
@classmethod
def from_config(cls, config: dict) -> 'PaymentGateway':
...
@staticmethod
def supported_currencies() -> list:
...
@property
def name(self) -> str:
"""The gateway display name."""
...
# Create reflection instance
reflection = ReflectionAbstract(PaymentGateway)
# Identity
print(reflection.getClassName())
# "PaymentGateway"
# Metadata
print(reflection.getDocstring())
# "Abstract payment gateway interface."
print(reflection.getBaseClasses())
# [<class 'abc.ABC'>]
# Attributes by visibility
print(reflection.getPublicAttributes())
# {"gateway_name": <class 'str'>} or attributes with assigned values
print(reflection.getProtectedAttributes())
# {"_timeout": 30}
print(reflection.getPrivateAttributes())
# {"__retries": 3}
# Methods
print(reflection.getPublicMethods())
# ["process_payment", "refund"]
print(reflection.getPublicSyncMethods())
# ["process_payment"]
print(reflection.getPublicAsyncMethods())
# ["refund"]
print(reflection.getPublicClassMethods())
# ["from_config"]
print(reflection.getPublicStaticMethods())
# ["supported_currencies"]
# Properties
print(reflection.getPublicProperties())
# ["name"]
print(reflection.getPropertyDocstring("name"))
# "The gateway display name."
# Method dependencies
sig = reflection.methodSignature("process_payment")
print(sig)
MethodReturnDescription
getClass()typeReturns the reflected abstract class
getClassName()strClass name
getModuleName()strModule where it is defined
getModuleWithClassName()strFull path module.Class
getDocstring()str | NoneClass docstring
getBaseClasses()list[type]Direct base classes
getSourceCode()strComplete source code
getFile()strAbsolute file path
getAnnotations()dictType annotations
hasAttribute(name)boolChecks attribute existence
getAttribute(name)object | NoneAttribute value
setAttribute(name, value)boolSets an attribute
removeAttribute(name)boolRemoves an attribute
getAttributes()dictAll attributes
getPublicAttributes()dictPublic attributes
getProtectedAttributes()dictProtected attributes
getPrivateAttributes()dictPrivate attributes
getDunderAttributes()dictDunder attributes
getMagicAttributes()dictAlias for getDunderAttributes
hasMethod(name)boolChecks method existence
removeMethod(name)boolRemoves a method
getMethodSignature(name)SignatureMethod signature
getMethods()list[str]All methods
getPublicMethods()list[str]Public methods
getPublicSyncMethods()list[str]Public synchronous methods
getPublicAsyncMethods()list[str]Public asynchronous methods
getProtectedMethods()list[str]Protected methods
getProtectedSyncMethods()list[str]Protected synchronous methods
getProtectedAsyncMethods()list[str]Protected asynchronous methods
getPrivateMethods()list[str]Private methods
getPrivateSyncMethods()list[str]Private synchronous methods
getPrivateAsyncMethods()list[str]Private asynchronous methods
getPublicClassMethods()list[str]Public class methods
getPublicClassSyncMethods()list[str]Public synchronous class methods
getPublicClassAsyncMethods()list[str]Public asynchronous class methods
getProtectedClassMethods()list[str]Protected class methods
getProtectedClassSyncMethods()list[str]Protected synchronous class methods
getProtectedClassAsyncMethods()list[str]Protected asynchronous class methods
getPrivateClassMethods()list[str]Private class methods
getPrivateClassSyncMethods()list[str]Private synchronous class methods
getPrivateClassAsyncMethods()list[str]Private asynchronous class methods
getPublicStaticMethods()list[str]Public static methods
getPublicStaticSyncMethods()list[str]Public synchronous static methods
getPublicStaticAsyncMethods()list[str]Public asynchronous static methods
getProtectedStaticMethods()list[str]Protected static methods
getProtectedStaticSyncMethods()list[str]Protected synchronous static methods
getProtectedStaticAsyncMethods()list[str]Protected asynchronous static methods
getPrivateStaticMethods()list[str]Private static methods
getPrivateStaticSyncMethods()list[str]Private synchronous static methods
getPrivateStaticAsyncMethods()list[str]Private asynchronous static methods
getDunderMethods()list[str]Dunder methods
getMagicMethods()list[str]Alias for getDunderMethods
getProperties()list[str]All properties
getPublicProperties()list[str]Public properties
getProtectedProperties()list[str]Protected properties
getPrivateProperties()list[str]Private properties
getPropertySignature(name)SignatureProperty getter signature
getPropertyDocstring(name)str | NoneGetter docstring
constructorSignature()SignatureConstructor dependencies
methodSignature(name)SignatureMethod dependencies
clearCache()NoneClears all cache