Concrete Classes
Reflection Concrete
Section titled “Reflection Concrete”The ReflectionConcrete class is an advanced introspection utility designed to analyze concrete Python classes at runtime. It provides a comprehensive API for inspecting attributes, methods, properties, metadata, and dependencies of any concrete (non-abstract) class registered in the Orionis framework.
Unlike ReflectionAbstract, which operates on abstract base classes, ReflectionConcrete focuses exclusively on instantiable classes with complete implementations. This makes it the ideal tool for analyzing services, controllers, models, and any concrete framework component.
Import
Section titled “Import”from orionis.services.introspection.concretes.reflection import ReflectionConcreteInitialization
Section titled “Initialization”The ReflectionConcrete class receives a valid concrete class as its parameter. If the provided class is abstract, a primitive type, a built-in, or not a class at all, a TypeError will be raised.
from orionis.services.introspection.concretes.reflection import ReflectionConcrete
class UserService: """Service for managing users."""
active: bool = True
def __init__(self, name: str = "default") -> None: self.name = name
def greet(self) -> str: return f"Hello, {self.name}"
reflection = ReflectionConcrete(UserService)If you pass an invalid type:
from abc import ABC, abstractmethod
class MyContract(ABC): @abstractmethod def execute(self) -> str: ...
# TypeError: abstract classReflectionConcrete(MyContract)
# TypeError: not a classReflectionConcrete(42)
# TypeError: built-inReflectionConcrete(len)Contract
Section titled “Contract”The ReflectionConcrete class implements the IReflectionConcrete contract, which defines the complete interface for concrete class introspection:
from orionis.services.introspection.concretes.contracts.reflection import IReflectionConcreteClass Identity
Section titled “Class Identity”These methods provide basic identification information about the reflected class.
getClass
Section titled “getClass”Returns the type (class) associated with the reflection instance.
cls = reflection.getClass()# <class 'UserService'>getClassName
Section titled “getClassName”Returns the simple name of the class as a string.
name = reflection.getClassName()# "UserService"getModuleName
Section titled “getModuleName”Returns the module name where the class is defined.
module = reflection.getModuleName()# "app.services.user_service"getModuleWithClassName
Section titled “getModuleWithClassName”Returns the fully qualified name (module + class).
fqn = reflection.getModuleWithClassName()# "app.services.user_service.UserService"Metadata
Section titled “Metadata”getDocstring
Section titled “getDocstring”Returns the class docstring, or None if not defined.
doc = reflection.getDocstring()# "Service for managing users."getBaseClasses
Section titled “getBaseClasses”Returns the list of direct base classes in resolution order.
bases = reflection.getBaseClasses()# [<class 'object'>]getSourceCode
Section titled “getSourceCode”Returns the source code of the entire class or a specific method. Returns None if the source is not available.
# Source code of the entire classsource = reflection.getSourceCode()
# Source code of a specific methodmethod_source = reflection.getSourceCode("greet")For private methods with name mangling, use the name without the prefix:
source = reflection.getSourceCode("__private_method")getFile
Section titled “getFile”Returns the absolute path of the file where the class is defined.
path = reflection.getFile()# "/app/services/user_service.py"getAnnotations
Section titled “getAnnotations”Returns a dictionary with the class type annotations. Automatically resolves name mangling for private attributes.
annotations = reflection.getAnnotations()# {"active": <class 'bool'>}Attributes
Section titled “Attributes”ReflectionConcrete classifies class attributes by visibility level, excluding methods, properties, staticmethod, and classmethod.
getAttributes
Section titled “getAttributes”Returns all class attributes, combining public, protected, private, and dunder.
attrs = reflection.getAttributes()getPublicAttributes
Section titled “getPublicAttributes”Returns public attributes (no underscore prefix).
public = reflection.getPublicAttributes()# {"active": True}getProtectedAttributes
Section titled “getProtectedAttributes”Returns protected attributes (_ prefix).
protected = reflection.getProtectedAttributes()# {"_internal_flag": False}getPrivateAttributes
Section titled “getPrivateAttributes”Returns private attributes (__ prefix). Names are returned without name mangling.
private = reflection.getPrivateAttributes()# {"__secret": "value"} — not "_ClassName__secret"getDunderAttributes / getMagicAttributes
Section titled “getDunderAttributes / getMagicAttributes”Returns custom dunder attributes of the class, excluding Python standard ones (__dict__, __module__, __doc__, etc.). getMagicAttributes is an alias for getDunderAttributes.
dunder = reflection.getDunderAttributes()magic = reflection.getMagicAttributes() # EquivalenthasAttribute
Section titled “hasAttribute”Checks whether an attribute exists in the class.
reflection.hasAttribute("active") # Truereflection.hasAttribute("missing") # FalsegetAttribute
Section titled “getAttribute”Gets the value of an attribute, with support for a default value.
value = reflection.getAttribute("active") # Truevalue = reflection.getAttribute("missing", "N/A") # "N/A"setAttribute
Section titled “setAttribute”Sets an attribute on the class. Only non-callable values are accepted; to add methods, use setMethod.
reflection.setAttribute("active", False) # TrueValidations:
- The name must be a valid Python identifier
- Cannot be a reserved keyword
- The value cannot be a callable (raises
TypeError)
removeAttribute
Section titled “removeAttribute”Removes an attribute from the class. Raises ValueError if the attribute does not exist.
reflection.removeAttribute("active") # TrueMethods
Section titled “Methods”ReflectionConcrete offers a granular API for inspecting methods organized along three axes: visibility (public, protected, private), type (instance, class, static, dunder), and nature (synchronous, asynchronous).
Inspection Methods Summary
Section titled “Inspection Methods Summary”| Method | Description |
|---|---|
getMethods() | All methods (instance + class + static) |
getPublicMethods() | Public instance methods |
getPublicSyncMethods() | Public synchronous |
getPublicAsyncMethods() | Public asynchronous |
getProtectedMethods() | Protected instance methods (_) |
getProtectedSyncMethods() | Protected synchronous |
getProtectedAsyncMethods() | Protected asynchronous |
getPrivateMethods() | Private instance methods (__) |
getPrivateSyncMethods() | Private synchronous |
getPrivateAsyncMethods() | Private asynchronous |
getPublicClassMethods() | Public class methods |
getPublicClassSyncMethods() | Public synchronous class methods |
getPublicClassAsyncMethods() | Public asynchronous class methods |
getProtectedClassMethods() | Protected class methods |
getProtectedClassSyncMethods() | Protected synchronous class methods |
getProtectedClassAsyncMethods() | Protected asynchronous class methods |
getPrivateClassMethods() | Private class methods |
getPrivateClassSyncMethods() | Private synchronous class methods |
getPrivateClassAsyncMethods() | Private asynchronous class methods |
getPublicStaticMethods() | Public static methods |
getPublicStaticSyncMethods() | Public synchronous static methods |
getPublicStaticAsyncMethods() | Public asynchronous static methods |
getProtectedStaticMethods() | Protected static methods |
getProtectedStaticSyncMethods() | Protected synchronous static methods |
getProtectedStaticAsyncMethods() | Protected asynchronous static methods |
getPrivateStaticMethods() | Private static methods |
getPrivateStaticSyncMethods() | Private synchronous static methods |
getPrivateStaticAsyncMethods() | Private asynchronous static methods |
getDunderMethods() | Dunder methods (__init__, __repr__, etc.) |
getMagicMethods() | Alias for getDunderMethods() |
All methods return list[str] with the names of the matching methods. Private method names are returned without name mangling.
Usage Example
Section titled “Usage Example”class MyService:
def process(self) -> str: return "done"
async def fetch(self) -> dict: return {}
def _validate(self) -> bool: return True
@classmethod def create(cls) -> "MyService": return cls()
@staticmethod def version() -> str: return "1.0"
reflection = ReflectionConcrete(MyService)
reflection.getPublicMethods() # ["process", "fetch"]reflection.getPublicSyncMethods() # ["process"]reflection.getPublicAsyncMethods() # ["fetch"]reflection.getProtectedMethods() # ["_validate"]reflection.getPublicClassMethods() # ["create"]reflection.getPublicStaticMethods() # ["version"]hasMethod
Section titled “hasMethod”Checks whether a method exists in the class (searches across all categories).
reflection.hasMethod("process") # Truereflection.hasMethod("missing") # FalsesetMethod
Section titled “setMethod”Adds a new method to the class. Raises ValueError if the name already exists or is invalid, and TypeError if the value is not callable.
def new_method(self) -> str: return "new"
reflection.setMethod("new_method", new_method) # TrueremoveMethod
Section titled “removeMethod”Removes a method from the class. Raises ValueError if the method does not exist.
reflection.removeMethod("new_method") # TruegetMethodSignature
Section titled “getMethodSignature”Returns the inspect.Signature object for a specific method.
sig = reflection.getMethodSignature("process")# (self) -> strProperties
Section titled “Properties”getProperties
Section titled “getProperties”Returns the names of all properties defined in the class.
class Config: @property def host(self) -> str: """Server hostname.""" return "localhost"
@property def _port(self) -> int: return 8080
reflection = ReflectionConcrete(Config)reflection.getProperties() # ["host", "_port"]Properties by Visibility
Section titled “Properties by Visibility”| Method | Description |
|---|---|
getPublicProperties() | Public properties |
getProtectedProperties() | Protected properties (_) |
getPrivateProperties() | Private properties (__, without mangling) |
getProperty
Section titled “getProperty”Retrieves the value of a property by executing its getter. Raises ValueError if it does not exist, or TypeError if it is not a property.
value = reflection.getProperty("host") # "localhost"getPropertySignature
Section titled “getPropertySignature”Returns the signature of a property’s getter.
sig = reflection.getPropertySignature("host")# (self) -> strgetPropertyDocstring
Section titled “getPropertyDocstring”Returns the docstring of a property’s getter, or None if not defined.
doc = reflection.getPropertyDocstring("host")# "Server hostname."Constructor and Dependencies
Section titled “Constructor and Dependencies”getConstructorSignature
Section titled “getConstructorSignature”Returns the inspect.Signature object for the __init__ method.
sig = reflection.getConstructorSignature()# (self, name: str = 'default') -> NoneconstructorSignature
Section titled “constructorSignature”Analyzes the constructor dependencies, identifying resolved parameters (with default values or primitive types) and unresolved parameters (requiring dependency injection).
analysis = reflection.constructorSignature()# Signature(resolved=[...], unresolved=[...])methodSignature
Section titled “methodSignature”Analyzes the dependencies of a specific method. Raises AttributeError if the method does not exist.
analysis = reflection.methodSignature("process")# Signature(resolved=[...], unresolved=[...])Internal Cache
Section titled “Internal Cache”ReflectionConcrete implements an in-memory caching system that stores the results of introspection operations. This avoids recomputing expensive results on repeated calls.
Cache Protocol
Section titled “Cache Protocol”The instance supports dictionary-style access for the cache:
# Check existence"key" in reflection
# Get value (None if not found)reflection["key"]
# Set valuereflection["key"] = value
# Delete entrydel reflection["key"]clearCache
Section titled “clearCache”Clears all cache entries. Subsequent method calls will recompute their results.
reflection.clearCache()