orionis 0.298.0__py3-none-any.whl → 0.299.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,9 +8,9 @@ from orionis.services.introspection.dependencies.reflect_dependencies import Ref
8
8
  from orionis.services.introspection.exceptions.reflection_attribute_error import ReflectionAttributeError
9
9
  from orionis.services.introspection.exceptions.reflection_type_error import ReflectionTypeError
10
10
  from orionis.services.introspection.exceptions.reflection_value_error import ReflectionValueError
11
- from orionis.services.introspection.instances.entities.class_property import ClassProperty
11
+ from orionis.services.introspection.instances.contracts.reflection_instance import IReflectionInstance
12
12
 
13
- class ReflectionInstance:
13
+ class ReflectionInstance(IReflectionInstance):
14
14
 
15
15
  def __init__(self, instance: Any) -> None:
16
16
  """
@@ -43,6 +43,17 @@ class ReflectionInstance:
43
43
  )
44
44
  self._instance = instance
45
45
 
46
+ def getInstance(self) -> Any:
47
+ """
48
+ Get the instance being reflected upon.
49
+
50
+ Returns
51
+ -------
52
+ Any
53
+ The object instance
54
+ """
55
+ return self._instance
56
+
46
57
  def getClass(self) -> Type:
47
58
  """
48
59
  Get the class of the instance.
@@ -524,6 +535,27 @@ class ReflectionInstance:
524
535
  # If the method is not callable, raise an error
525
536
  raise ReflectionAttributeError(f"Method '{name}' is not callable on '{self.getClassName()}'.")
526
537
 
538
+ def getMethods(self) -> List[str]:
539
+ """
540
+ Get all method names of the instance.
541
+
542
+ Returns
543
+ -------
544
+ List[str]
545
+ List of method names
546
+ """
547
+ return [
548
+ *self.getPublicMethods(),
549
+ *self.getProtectedMethods(),
550
+ *self.getPrivateMethods(),
551
+ *self.getPublicClassMethods(),
552
+ *self.getProtectedClassMethods(),
553
+ *self.getPrivateClassMethods(),
554
+ *self.getPublicStaticMethods(),
555
+ *self.getProtectedStaticMethods(),
556
+ *self.getPrivateStaticMethods(),
557
+ ]
558
+
527
559
  def getPublicMethods(self) -> List[str]:
528
560
  """
529
561
  Get all public method names of the instance.
@@ -680,20 +712,6 @@ class ReflectionInstance:
680
712
  private_methods.append(short_name)
681
713
  return private_methods
682
714
 
683
-
684
-
685
-
686
-
687
-
688
-
689
-
690
-
691
-
692
-
693
-
694
-
695
-
696
-
697
715
  def getPublicClassMethods(self) -> List[str]:
698
716
  """
699
717
  Get all class method names of the instance.
@@ -786,45 +804,78 @@ class ReflectionInstance:
786
804
  # Return the list of public asynchronous class method names
787
805
  return public_class_async_methods
788
806
 
807
+ def getProtectedClassMethods(self) -> List[str]:
808
+ """
809
+ Get all protected class method names of the instance.
789
810
 
811
+ Returns
812
+ -------
813
+ List[str]
814
+ List of protected class method names
815
+ """
816
+ cls = self._instance.__class__
817
+ class_methods = []
790
818
 
819
+ # Iterate over all attributes of the class
820
+ for name in dir(cls):
791
821
 
822
+ # Get the attribute using getattr_static to avoid triggering property getters
823
+ attr = inspect.getattr_static(cls, name)
792
824
 
825
+ # Check if the attribute is a class method
826
+ if isinstance(attr, classmethod):
793
827
 
828
+ # Check is a protected class method
829
+ if name.startswith(f"_") and not name.startswith("__") and not name.startswith(f"_{self.getClassName()}"):
830
+ class_methods.append(name)
794
831
 
832
+ # Return the list of public class method
833
+ return class_methods
795
834
 
835
+ def getProtectedClassSyncMethods(self) -> List[str]:
836
+ """
837
+ Get all protected synchronous class method names of the instance.
796
838
 
839
+ Returns
840
+ -------
841
+ List[str]
842
+ List of protected synchronous class method names
843
+ """
844
+ class_name = self.getClassName()
845
+ cls = self._instance.__class__
846
+ protected_class_sync_methods = []
797
847
 
848
+ # Iterate over all attributes of the class
849
+ for name in dir(cls):
798
850
 
851
+ # Get the attribute using getattr_static to avoid triggering property getters
852
+ attr = inspect.getattr_static(cls, name)
799
853
 
854
+ # Check if the attribute is a class method
855
+ if isinstance(attr, classmethod):
800
856
 
857
+ # Get the underlying function
858
+ func = attr.__func__
801
859
 
860
+ # Check if it's NOT a coroutine function (i.e., synchronous)
861
+ if not inspect.iscoroutinefunction(func) and name.startswith(f"_") and not name.startswith(f"_{class_name}"):
862
+ protected_class_sync_methods.append(str(name).replace(f"_{class_name}", ""))
802
863
 
864
+ # Return the list of protected class method names
865
+ return protected_class_sync_methods
803
866
 
804
-
805
-
806
-
807
-
808
-
809
-
810
-
811
-
812
-
813
-
814
-
815
-
816
- def getProtectedClassMethods(self) -> List[str]:
867
+ def getProtectedClassAsyncMethods(self) -> List[str]:
817
868
  """
818
- Get all protected class method names of the instance.
869
+ Get all protected asynchronous class method names of the instance.
819
870
 
820
871
  Returns
821
872
  -------
822
873
  List[str]
823
- List of protected class method names
874
+ List of protected asynchronous class method names
824
875
  """
825
876
  class_name = self.getClassName()
826
877
  cls = self._instance.__class__
827
- protected_class_methods = []
878
+ protected_class_async_methods = []
828
879
 
829
880
  # Iterate over all attributes of the class
830
881
  for name in dir(cls):
@@ -838,12 +889,12 @@ class ReflectionInstance:
838
889
  # Get the underlying function
839
890
  func = attr.__func__
840
891
 
841
- # Check if it's NOT a coroutine function (i.e., synchronous)
842
- if not inspect.iscoroutinefunction(func) and name.startswith(f"_") and not name.startswith("__") and not name.startswith(f"_{class_name}"):
843
- protected_class_methods.append(str(name).replace(f"_{class_name}", ""))
892
+ # Check if it's a coroutine function (i.e., asynchronous)
893
+ if inspect.iscoroutinefunction(func) and name.startswith(f"_") and not name.startswith(f"_{class_name}"):
894
+ protected_class_async_methods.append(str(name).replace(f"_{class_name}", ""))
844
895
 
845
- # Return the list of protected class method names
846
- return protected_class_methods
896
+ # Return the list of protected asynchronous class method names
897
+ return protected_class_async_methods
847
898
 
848
899
  def getPrivateClassMethods(self) -> List[str]:
849
900
  """
@@ -870,41 +921,25 @@ class ReflectionInstance:
870
921
  # Get the underlying function
871
922
  func = attr.__func__
872
923
 
873
- # Check if it's NOT a coroutine function (i.e., synchronous)
874
- if not inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
924
+ # Check if a private class method
925
+ if name.startswith(f"_{class_name}"):
875
926
  private_class_methods.append(str(name).replace(f"_{class_name}", ""))
876
927
 
877
928
  # Return the list of protected class method names
878
929
  return private_class_methods
879
930
 
880
-
881
-
882
-
883
-
884
-
885
-
886
-
887
-
888
-
889
-
890
-
891
-
892
-
893
-
894
-
895
-
896
- def getClassSyncMethods(self) -> List[str]:
931
+ def getPrivateClassSyncMethods(self) -> List[str]:
897
932
  """
898
- Get all synchronous class method names of the instance.
933
+ Get all private synchronous class method names of the instance.
899
934
 
900
935
  Returns
901
936
  -------
902
937
  List[str]
903
- List of synchronous class method names
938
+ List of private synchronous class method names
904
939
  """
905
940
  class_name = self.getClassName()
906
941
  cls = self._instance.__class__
907
- class_sync_methods = []
942
+ private_class_sync_methods = []
908
943
 
909
944
  # Iterate over all attributes of the class
910
945
  for name in dir(cls):
@@ -919,24 +954,24 @@ class ReflectionInstance:
919
954
  func = attr.__func__
920
955
 
921
956
  # Check if it's NOT a coroutine function (i.e., synchronous)
922
- if not inspect.iscoroutinefunction(func):
923
- class_sync_methods.append(str(name).replace(f"_{class_name}", ""))
957
+ if not inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
958
+ private_class_sync_methods.append(str(name).replace(f"_{class_name}", ""))
924
959
 
925
- # Return the list of synchronous class method names
926
- return class_sync_methods
960
+ # Return the list of private synchronous class method names
961
+ return private_class_sync_methods
927
962
 
928
- def getClassAsyncMethods(self) -> List[str]:
963
+ def getPrivateClassAsyncMethods(self) -> List[str]:
929
964
  """
930
- Get all asynchronous class method names of the instance.
965
+ Get all private asynchronous class method names of the instance.
931
966
 
932
967
  Returns
933
968
  -------
934
969
  List[str]
935
- List of asynchronous class method names
970
+ List of private asynchronous class method names
936
971
  """
937
972
  class_name = self.getClassName()
938
973
  cls = self._instance.__class__
939
- class_async_methods = []
974
+ private_class_async_methods = []
940
975
 
941
976
  # Iterate over all attributes of the class
942
977
  for name in dir(cls):
@@ -951,104 +986,41 @@ class ReflectionInstance:
951
986
  func = attr.__func__
952
987
 
953
988
  # Check if it's a coroutine function (i.e., asynchronous)
954
- if inspect.iscoroutinefunction(func):
955
- class_async_methods.append(str(name).replace(f"_{class_name}", ""))
956
-
957
- # Return the list of asynchronous class method names
958
- return class_async_methods
959
-
960
-
961
-
962
-
989
+ if inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
990
+ private_class_async_methods.append(str(name).replace(f"_{class_name}", ""))
963
991
 
992
+ # Return the list of private asynchronous class method names
993
+ return private_class_async_methods
964
994
 
965
-
966
-
967
-
968
-
969
-
970
-
971
-
972
-
973
-
974
-
975
-
976
-
977
-
978
-
979
-
980
-
981
-
982
-
983
-
984
-
985
-
986
-
987
-
988
-
989
-
990
-
991
- def getDunderMethods(self) -> List[str]:
995
+ def getPublicStaticMethods(self) -> List[str]:
992
996
  """
993
- Get all dunder (double underscore) method names of the instance.
994
-
995
- Returns
996
- -------
997
- List[str]
998
- List of dunder method names
999
- """
1000
- dunder_methods = []
1001
-
1002
- # Collect dunder methods (starting and ending with double underscores)
1003
- for name in dir(self._instance):
1004
- if name.startswith("__") and name.endswith("__"):
1005
- dunder_methods.append(name)
1006
-
1007
- return dunder_methods
1008
-
1009
- def getMagicMethods(self) -> List[str]:
1010
- """
1011
- Get all magic method names of the instance.
1012
-
1013
- Returns
1014
- -------
1015
- List[str]
1016
- List of magic method names
1017
- """
1018
- return self.getDunderMethods()
1019
-
1020
-
1021
-
1022
- def getStaticMethods(self) -> List[str]:
1023
- """
1024
- Get all static method names of the instance.
997
+ Get public static method names of the instance.
1025
998
 
1026
999
  Returns
1027
1000
  -------
1028
1001
  List[str]
1029
1002
  List of static method names
1030
1003
  """
1031
- class_name = self.getClassName()
1032
1004
  cls = self._instance.__class__
1033
1005
  static_methods = []
1034
1006
  for name in dir(cls):
1035
1007
  attr = inspect.getattr_static(cls, name)
1036
- if isinstance(attr, staticmethod):
1037
- static_methods.append(str(name).replace(f"_{class_name}", ""))
1008
+ if isinstance(attr, staticmethod) and not name.startswith(f"_"):
1009
+ static_methods.append(name)
1038
1010
  return static_methods
1039
1011
 
1040
- def getStaticSyncMethods(self) -> List[str]:
1012
+ def getPublicStaticSyncMethods(self) -> List[str]:
1041
1013
  """
1042
- Get all synchronous static method names of the instance.
1014
+ Get all public synchronous static method names of the instance.
1043
1015
 
1044
1016
  Returns
1045
1017
  -------
1046
1018
  List[str]
1047
- List of synchronous static method names
1019
+ List of public synchronous static method names
1048
1020
  """
1049
1021
  class_name = self.getClassName()
1050
1022
  cls = self._instance.__class__
1051
- static_sync_methods = []
1023
+ public_static_sync_methods = []
1052
1024
 
1053
1025
  # Iterate over all attributes of the class
1054
1026
  for name in dir(cls):
@@ -1063,24 +1035,24 @@ class ReflectionInstance:
1063
1035
  func = attr.__func__
1064
1036
 
1065
1037
  # Check if it's NOT a coroutine function (i.e., synchronous)
1066
- if not inspect.iscoroutinefunction(func):
1067
- static_sync_methods.append(str(name).replace(f"_{class_name}", ""))
1038
+ if not inspect.iscoroutinefunction(func) and not name.startswith(f"_"):
1039
+ public_static_sync_methods.append(str(name).replace(f"_{class_name}", ""))
1068
1040
 
1069
- # Return the list of synchronous static method names
1070
- return static_sync_methods
1041
+ # Return the list of public synchronous static method names
1042
+ return public_static_sync_methods
1071
1043
 
1072
- def getStaticAsyncMethods(self) -> List[str]:
1044
+ def getPublicStaticAsyncMethods(self) -> List[str]:
1073
1045
  """
1074
- Get all asynchronous static method names of the instance.
1046
+ Get all public asynchronous static method names of the instance.
1075
1047
 
1076
1048
  Returns
1077
1049
  -------
1078
1050
  List[str]
1079
- List of asynchronous static method names
1051
+ List of public asynchronous static method names
1080
1052
  """
1081
1053
  class_name = self.getClassName()
1082
1054
  cls = self._instance.__class__
1083
- static_async_methods = []
1055
+ public_static_async_methods = []
1084
1056
 
1085
1057
  # Iterate over all attributes of the class
1086
1058
  for name in dir(cls):
@@ -1095,312 +1067,370 @@ class ReflectionInstance:
1095
1067
  func = attr.__func__
1096
1068
 
1097
1069
  # Check if it's a coroutine function (i.e., asynchronous)
1098
- if inspect.iscoroutinefunction(func):
1099
- static_async_methods.append(str(name).replace(f"_{class_name}", ""))
1100
-
1101
- # Return the list of asynchronous static method names
1102
- return static_async_methods
1103
-
1104
- # def getMethodDocstring(self, method_name: str) -> Optional[str]:
1105
- # """
1106
- # Get the docstring of a method.
1107
-
1108
- # Parameters
1109
- # ----------
1110
- # method_name : str
1111
- # Name of the method
1112
-
1113
- # Returns
1114
- # -------
1115
- # Optional[str]
1116
- # The docstring of the method, or None if not available
1117
- # """
1118
- # # Handle private method name mangling
1119
- # if method_name in self.getPrivateMethods() or method_name in self.getClass
1120
- # method_name = f"_{self.getClassName()}{method_name}"
1121
-
1122
- # print(f"Getting docstring for method: {method_name} in class: {self.getPrivateMethods()}")
1123
-
1124
- # # Try to get the method from the instance first
1125
- # method = getattr(self._instance, method_name, None)
1126
- # if method is None:
1127
- # # Try to get the method from the class if not found on the instance
1128
- # method = getattr(self._instance.__class__, method_name, None)
1129
- # if method is None:
1130
- # return None
1131
-
1132
- # # If it's a staticmethod or classmethod, get the underlying function
1133
- # if isinstance(method, (staticmethod, classmethod)):
1134
- # method = method.__func__
1135
-
1136
- # # Return the docstring if available
1137
- # return getattr(method, "__doc__", None) or ""
1138
-
1139
- # def getMethodSignature(self, method_name: str) -> inspect.Signature:
1140
- # """
1141
- # Get the signature of a method.
1142
-
1143
- # Parameters
1144
- # ----------
1145
- # method_name : str
1146
- # Name of the method
1147
-
1148
- # Returns
1149
- # -------
1150
- # inspect.Signature
1151
- # The method signature
1152
-
1153
- # Raises
1154
- # ------
1155
- # ReflectionAttributeError
1156
- # If the method does not exist on the instance
1157
- # """
1158
- # if method_name in self.getPrivateMethods():
1159
- # method_name = f"_{self.getClassName()}{method_name}"
1160
-
1161
- # method = getattr(self._instance, method_name, None)
1162
- # if method is None or not callable(method):
1163
- # raise ReflectionAttributeError(f"Method '{method_name}' not found in '{self.getClassName()}'.")
1164
-
1165
- # return inspect.signature(method)
1166
-
1167
-
1168
-
1169
-
1170
-
1171
-
1172
-
1173
-
1174
-
1175
-
1176
-
1177
-
1178
-
1179
-
1180
-
1181
-
1182
-
1183
-
1184
-
1185
-
1186
-
1187
-
1188
-
1070
+ if inspect.iscoroutinefunction(func) and not name.startswith(f"_"):
1071
+ public_static_async_methods.append(str(name).replace(f"_{class_name}", ""))
1189
1072
 
1073
+ # Return the list of public asynchronous static method names
1074
+ return public_static_async_methods
1190
1075
 
1076
+ def getProtectedStaticMethods(self) -> List[str]:
1077
+ """
1078
+ Get all protected static method names of the instance.
1191
1079
 
1080
+ Returns
1081
+ -------
1082
+ List[str]
1083
+ List of protected static method names
1084
+ """
1085
+ cls = self._instance.__class__
1086
+ protected_static_methods = []
1192
1087
 
1088
+ # Iterate over all attributes of the class
1089
+ for name in dir(cls):
1193
1090
 
1091
+ # Get the attribute using getattr_static to avoid triggering property getters
1092
+ attr = inspect.getattr_static(cls, name)
1194
1093
 
1094
+ # Check if the attribute is a static method
1095
+ if isinstance(attr, staticmethod) and name.startswith(f"_") and not name.startswith("__") and not name.startswith(f"_{self.getClassName()}"):
1096
+ protected_static_methods.append(name)
1195
1097
 
1098
+ return protected_static_methods
1196
1099
 
1100
+ def getProtectedStaticSyncMethods(self) -> List[str]:
1101
+ """
1102
+ Get all protected synchronous static method names of the instance.
1197
1103
 
1104
+ Returns
1105
+ -------
1106
+ List[str]
1107
+ List of protected synchronous static method names
1108
+ """
1109
+ class_name = self.getClassName()
1110
+ cls = self._instance.__class__
1111
+ protected_static_sync_methods = []
1198
1112
 
1113
+ # Iterate over all attributes of the class
1114
+ for name in dir(cls):
1199
1115
 
1116
+ # Get the attribute using getattr_static to avoid triggering property getters
1117
+ attr = inspect.getattr_static(cls, name)
1200
1118
 
1119
+ # Check if the attribute is a static method
1120
+ if isinstance(attr, staticmethod):
1201
1121
 
1122
+ # Get the underlying function
1123
+ func = attr.__func__
1202
1124
 
1125
+ # Check if it's NOT a coroutine function (i.e., synchronous)
1126
+ if not inspect.iscoroutinefunction(func) and name.startswith(f"_") and not name.startswith(f"_{class_name}"):
1127
+ protected_static_sync_methods.append(str(name).replace(f"_{class_name}", ""))
1203
1128
 
1129
+ return protected_static_sync_methods
1204
1130
 
1131
+ def getProtectedStaticAsyncMethods(self) -> List[str]:
1132
+ """
1133
+ Get all protected asynchronous static method names of the instance.
1205
1134
 
1135
+ Returns
1136
+ -------
1137
+ List[str]
1138
+ List of protected asynchronous static method names
1139
+ """
1140
+ class_name = self.getClassName()
1141
+ cls = self._instance.__class__
1142
+ protected_static_async_methods = []
1206
1143
 
1144
+ # Iterate over all attributes of the class
1145
+ for name in dir(cls):
1207
1146
 
1147
+ # Get the attribute using getattr_static to avoid triggering property getters
1148
+ attr = inspect.getattr_static(cls, name)
1208
1149
 
1150
+ # Check if the attribute is a static method
1151
+ if isinstance(attr, staticmethod):
1209
1152
 
1153
+ # Get the underlying function
1154
+ func = attr.__func__
1210
1155
 
1156
+ # Check if it's a coroutine function (i.e., asynchronous)
1157
+ if inspect.iscoroutinefunction(func) and name.startswith(f"_") and not name.startswith(f"_{class_name}"):
1158
+ protected_static_async_methods.append(str(name).replace(f"_{class_name}", ""))
1211
1159
 
1160
+ return protected_static_async_methods
1212
1161
 
1162
+ def getPrivateStaticMethods(self) -> List[str]:
1163
+ """
1164
+ Get all private static method names of the instance.
1213
1165
 
1166
+ Returns
1167
+ -------
1168
+ List[str]
1169
+ List of private static method names
1170
+ """
1171
+ class_name = self.getClassName()
1172
+ cls = self._instance.__class__
1173
+ private_static_methods = []
1214
1174
 
1175
+ # Iterate over all attributes of the class
1176
+ for name in dir(cls):
1215
1177
 
1178
+ # Get the attribute using getattr_static to avoid triggering property getters
1179
+ attr = inspect.getattr_static(cls, name)
1216
1180
 
1181
+ # Check if the attribute is a static method
1182
+ if isinstance(attr, staticmethod):
1217
1183
 
1184
+ # Check if a private static method
1185
+ if name.startswith(f"_{class_name}"):
1186
+ private_static_methods.append(str(name).replace(f"_{class_name}", ""))
1218
1187
 
1188
+ return private_static_methods
1219
1189
 
1190
+ def getPrivateStaticSyncMethods(self) -> List[str]:
1191
+ """
1192
+ Get all private synchronous static method names of the instance.
1220
1193
 
1194
+ Returns
1195
+ -------
1196
+ List[str]
1197
+ List of private synchronous static method names
1198
+ """
1199
+ class_name = self.getClassName()
1200
+ cls = self._instance.__class__
1201
+ private_static_sync_methods = []
1221
1202
 
1203
+ # Iterate over all attributes of the class
1204
+ for name in dir(cls):
1222
1205
 
1206
+ # Get the attribute using getattr_static to avoid triggering property getters
1207
+ attr = inspect.getattr_static(cls, name)
1223
1208
 
1209
+ # Check if the attribute is a static method
1210
+ if isinstance(attr, staticmethod):
1224
1211
 
1212
+ # Get the underlying function
1213
+ func = attr.__func__
1225
1214
 
1215
+ # Check if it's NOT a coroutine function (i.e., synchronous)
1216
+ if not inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
1217
+ private_static_sync_methods.append(str(name).replace(f"_{class_name}", ""))
1226
1218
 
1219
+ return private_static_sync_methods
1227
1220
 
1221
+ def getPrivateStaticAsyncMethods(self) -> List[str]:
1222
+ """
1223
+ Get all private asynchronous static method names of the instance.
1228
1224
 
1225
+ Returns
1226
+ -------
1227
+ List[str]
1228
+ List of private asynchronous static method names
1229
+ """
1230
+ class_name = self.getClassName()
1231
+ cls = self._instance.__class__
1232
+ private_static_async_methods = []
1229
1233
 
1234
+ # Iterate over all attributes of the class
1235
+ for name in dir(cls):
1230
1236
 
1237
+ # Get the attribute using getattr_static to avoid triggering property getters
1238
+ attr = inspect.getattr_static(cls, name)
1231
1239
 
1240
+ # Check if the attribute is a static method
1241
+ if isinstance(attr, staticmethod):
1232
1242
 
1243
+ # Get the underlying function
1244
+ func = attr.__func__
1233
1245
 
1246
+ # Check if it's a coroutine function (i.e., asynchronous)
1247
+ if inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
1248
+ private_static_async_methods.append(str(name).replace(f"_{class_name}", ""))
1234
1249
 
1250
+ return private_static_async_methods
1235
1251
 
1252
+ def getDunderMethods(self) -> List[str]:
1253
+ """
1254
+ Get all dunder (double underscore) method names of the instance.
1236
1255
 
1256
+ Returns
1257
+ -------
1258
+ List[str]
1259
+ List of dunder method names
1260
+ """
1261
+ dunder_methods = []
1237
1262
 
1263
+ # Collect dunder methods (starting and ending with double underscores)
1264
+ for name in dir(self._instance):
1265
+ if name.startswith("__") and name.endswith("__"):
1266
+ dunder_methods.append(name)
1238
1267
 
1268
+ return dunder_methods
1239
1269
 
1270
+ def getMagicMethods(self) -> List[str]:
1271
+ """
1272
+ Get all magic method names of the instance.
1240
1273
 
1274
+ Returns
1275
+ -------
1276
+ List[str]
1277
+ List of magic method names
1278
+ """
1279
+ return self.getDunderMethods()
1241
1280
 
1281
+ def getProperties(self) -> Dict:
1282
+ """
1283
+ Get all properties of the instance.
1242
1284
 
1285
+ Returns
1286
+ -------
1287
+ List[str]
1288
+ List of property names
1289
+ """
1243
1290
 
1291
+ properties = {}
1292
+ for name, prop in self._instance.__class__.__dict__.items():
1293
+ if isinstance(prop, property):
1294
+ name = name.replace(f"_{self.getClassName()}", "")
1295
+ properties[name] = getattr(self._instance, name, None)
1296
+ return properties
1244
1297
 
1298
+ def getPublicProperties(self) -> Dict:
1299
+ """
1300
+ Get all public properties of the instance.
1245
1301
 
1302
+ Returns
1303
+ -------
1304
+ Dict[str]
1305
+ Dictionary of public property names and their values
1306
+ """
1307
+ properties = {}
1308
+ for name, prop in self._instance.__class__.__dict__.items():
1309
+ if isinstance(prop, property):
1310
+ if not name.startswith(f"_"):
1311
+ properties[name] = getattr(self._instance, name, None)
1312
+ return properties
1246
1313
 
1247
- def getProperties(self) -> Dict[str, ClassProperty]:
1314
+ def getProtectedProperties(self) -> Dict:
1248
1315
  """
1249
- Get all properties of the instance.
1316
+ Get all protected properties of the instance.
1250
1317
 
1251
1318
  Returns
1252
1319
  -------
1253
- List[str]
1254
- List of property names
1320
+ Dict[str]
1321
+ Dictionary of protected property names and their values
1255
1322
  """
1256
-
1257
1323
  properties = {}
1258
1324
  for name, prop in self._instance.__class__.__dict__.items():
1259
1325
  if isinstance(prop, property):
1260
- properties[name] = ClassProperty(
1261
- name=name,
1262
- value=getattr(self._instance, name, None),
1263
- signature=inspect.signature(prop.fget) if prop.fget else None,
1264
- doc=prop.__doc__ or ""
1265
- )
1326
+ if name.startswith(f"_") and not name.startswith("__") and not name.startswith(f"_{self.getClassName()}"):
1327
+ properties[name] = getattr(self._instance, name, None)
1266
1328
  return properties
1267
1329
 
1268
- def getPropertyNames(self) -> List[str]:
1330
+ def getPrivateProperties(self) -> Dict:
1269
1331
  """
1270
- Get all property names of the instance.
1332
+ Get all private properties of the instance.
1271
1333
 
1272
1334
  Returns
1273
1335
  -------
1274
- List[str]
1275
- List of property names
1336
+ Dict[str]
1337
+ Dictionary of private property names and their values
1276
1338
  """
1277
- return self.getProperties().keys()
1339
+ properties = {}
1340
+ for name, prop in self._instance.__class__.__dict__.items():
1341
+ if isinstance(prop, property):
1342
+ if name.startswith(f"_{self.getClassName()}") and not name.startswith("__"):
1343
+ properties[name.replace(f"_{self.getClassName()}", "")] = getattr(self._instance, name, None)
1344
+ return properties
1278
1345
 
1279
- def getProperty(self, property_name: str) -> Any:
1346
+ def getPropierty(self, name: str) -> Any:
1280
1347
  """
1281
- Get the value of a property.
1348
+ Get a specific property of the instance.
1282
1349
 
1283
1350
  Parameters
1284
1351
  ----------
1285
- property_name : str
1286
- Name of the property
1352
+ name : str
1353
+ The name of the property to retrieve
1287
1354
 
1288
1355
  Returns
1289
1356
  -------
1290
- Any
1291
- The value of the property
1357
+ ClassProperty
1358
+ The value of the specified property
1292
1359
 
1293
1360
  Raises
1294
1361
  ------
1295
- AttributeError
1296
- If the property doesn't exist or is not a property
1362
+ ReflectionAttributeError
1363
+ If the property does not exist or is not accessible
1297
1364
  """
1298
- all_prop = self.getProperties()
1299
- if property_name not in all_prop:
1300
- raise ReflectionValueError(f"Property '{property_name}' not found.")
1301
- return all_prop[property_name].value
1365
+ # Check if the property name is valid
1366
+ if name in self.getProperties():
1367
+
1368
+ # Handle private property name mangling
1369
+ if name.startswith("__") and not name.endswith("__"):
1370
+ class_name = self.getClassName()
1371
+ name = f"_{class_name}{name}"
1302
1372
 
1303
- def getPropertySignature(self, property_name: str) -> inspect.Signature:
1373
+ # Return the property value from the instance
1374
+ return getattr(self._instance, name, None)
1375
+
1376
+ # If the property does not exist, raise an error
1377
+ raise ReflectionAttributeError(f"Property '{name}' does not exist on '{self.getClassName()}'.")
1378
+
1379
+ def getPropertySignature(self, name: str) -> inspect.Signature:
1304
1380
  """
1305
1381
  Get the signature of a property.
1306
1382
 
1307
1383
  Parameters
1308
1384
  ----------
1309
- property_name : str
1385
+ name : str
1310
1386
  Name of the property
1311
1387
 
1312
1388
  Returns
1313
1389
  -------
1314
1390
  inspect.Signature
1315
1391
  The property signature
1316
-
1317
- Raises
1318
- ------
1319
- AttributeError
1320
- If the property doesn't exist or is not a property
1321
1392
  """
1322
- all_prop = self.getProperties()
1323
- if property_name not in all_prop:
1324
- raise ReflectionValueError(f"Property '{property_name}' not found.")
1325
- return all_prop[property_name].signature
1393
+ # Handle private property name mangling
1394
+ original_name = name
1395
+ if name.startswith("__") and not name.endswith("__"):
1396
+ class_name = self.getClassName()
1397
+ name = f"_{class_name}{name}"
1326
1398
 
1327
- def getPropertyDoc(self, property_name: str) -> str:
1399
+ # Check if the property exists
1400
+ prop = getattr(self._instance.__class__, name, None)
1401
+ if isinstance(prop, property):
1402
+ return inspect.signature(prop.fget)
1403
+
1404
+ # If the property does not exist, raise an error
1405
+ raise ReflectionAttributeError(f"Property '{original_name}' does not exist on '{self.getClassName()}'.")
1406
+
1407
+ def getPropiertyDocstring(self, name: str) -> str:
1328
1408
  """
1329
1409
  Get the docstring of a property.
1330
1410
 
1331
1411
  Parameters
1332
1412
  ----------
1333
- property_name : str
1413
+ name : str
1334
1414
  Name of the property
1335
1415
 
1336
1416
  Returns
1337
1417
  -------
1338
1418
  str
1339
1419
  The docstring of the property
1340
-
1341
- Raises
1342
- ------
1343
- AttributeError
1344
- If the property doesn't exist or is not a property
1345
1420
  """
1346
- all_prop = self.getProperties()
1347
- if property_name not in all_prop:
1348
- raise ReflectionValueError(f"Property '{property_name}' not found.")
1349
- return all_prop[property_name].doc
1350
-
1351
-
1352
-
1353
-
1354
-
1355
-
1356
-
1357
-
1358
-
1359
-
1360
-
1361
-
1362
-
1363
-
1364
-
1365
-
1366
-
1367
-
1368
-
1369
-
1370
-
1371
-
1372
-
1373
-
1374
-
1375
-
1376
-
1377
-
1378
-
1379
-
1380
-
1381
-
1382
-
1383
-
1384
-
1385
-
1386
-
1387
-
1388
-
1389
-
1390
-
1391
-
1392
-
1393
-
1394
-
1395
-
1396
-
1397
-
1398
-
1399
-
1400
-
1421
+ # Handle private property name mangling
1422
+ original_name = name
1423
+ if name.startswith("__") and not name.endswith("__"):
1424
+ class_name = self.getClassName()
1425
+ name = f"_{class_name}{name}"
1401
1426
 
1402
-
1427
+ # Check if the property exists
1428
+ prop = getattr(self._instance.__class__, name, None)
1429
+ if isinstance(prop, property):
1430
+ return prop.fget.__doc__ or ""
1403
1431
 
1432
+ # If the property does not exist, raise an error
1433
+ raise ReflectionAttributeError(f"Property '{original_name}' does not exist on '{self.getClassName()}'.")
1404
1434
 
1405
1435
  def getConstructorDependencies(self) -> ClassDependency:
1406
1436
  """
@@ -1433,4 +1463,15 @@ class ReflectionInstance:
1433
1463
  - resolved: Dictionary of resolved dependencies with their names and values.
1434
1464
  - unresolved: List of unresolved dependencies (parameter names without default values or annotations).
1435
1465
  """
1436
- return ReflectDependencies(self._instance).getMethodDependencies(method_name)
1466
+
1467
+ # Ensure the method name is a valid identifier
1468
+ if not self.hasMethod(method_name):
1469
+ raise ReflectionAttributeError(f"Method '{method_name}' does not exist on '{self.getClassName()}'.")
1470
+
1471
+ # Handle private method name mangling
1472
+ if method_name.startswith("__") and not method_name.endswith("__"):
1473
+ class_name = self.getClassName()
1474
+ method_name = f"_{class_name}{method_name}"
1475
+
1476
+ # Use ReflectDependencies to get method dependencies
1477
+ return ReflectDependencies(self._instance).getMethodDependencies(method_name)