orionis 0.298.0__py3-none-any.whl → 0.300.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.
@@ -208,7 +219,7 @@ class ReflectionInstance:
208
219
 
209
220
  # Ensure the value is not callable
210
221
  if callable(value):
211
- raise ReflectionAttributeError(f"Cannot set attribute '{name}' to a callable. Use setMacro instead.")
222
+ raise ReflectionAttributeError(f"Cannot set attribute '{name}' to a callable. Use setMethod instead.")
212
223
 
213
224
  # Handle private attribute name mangling
214
225
  if name.startswith("__") and not name.endswith("__"):
@@ -368,23 +379,7 @@ class ReflectionInstance:
368
379
  bool
369
380
  True if the method exists, False otherwise
370
381
  """
371
- # Handle private method name mangling
372
- if name.startswith("__") and not name.endswith("__"):
373
- class_name = self.getClassName()
374
- name = f"_{class_name}{name}"
375
-
376
- # Check if the method is callable
377
- if hasattr(self._instance, name):
378
- return callable(getattr(self._instance, name, None))
379
-
380
- # Check if the method is a class method or static method
381
- cls = self._instance.__class__
382
- if hasattr(cls, name):
383
- attr = inspect.getattr_static(cls, name)
384
- return isinstance(attr, (classmethod, staticmethod)) and callable(attr.__func__)
385
-
386
- # If not found, return False
387
- return False
382
+ return name in self.getMethods()
388
383
 
389
384
  def callMethod(self, name: str, *args: Any, **kwargs: Any) -> Any:
390
385
  """
@@ -440,15 +435,15 @@ class ReflectionInstance:
440
435
  # Call the method with provided arguments
441
436
  return method(*args, **kwargs)
442
437
 
443
- def setMethod(self, name: str, value: Callable) -> bool:
438
+ def setMethod(self, name: str, method: Callable) -> bool:
444
439
  """
445
- Set a callable attribute value.
440
+ Set a callable attribute method.
446
441
 
447
442
  Parameters
448
443
  ----------
449
444
  name : str
450
445
  The attribute name
451
- value : Callable
446
+ method : Callable
452
447
  The callable to set
453
448
 
454
449
  Raises
@@ -460,10 +455,26 @@ class ReflectionInstance:
460
455
  if not isinstance(name, str) or not name.isidentifier() or keyword.iskeyword(name):
461
456
  raise ReflectionAttributeError(f"Invalid method name '{name}'. Must be a valid Python identifier and not a keyword.")
462
457
 
463
- # Ensure the value is callable
464
- if not callable(value):
458
+ # Ensure the method is callable
459
+ if not callable(method):
465
460
  raise ReflectionAttributeError(f"Cannot set attribute '{name}' to a non-callable value.")
466
461
 
462
+ # Extarct the signature of the method and classtype
463
+ sign = inspect.signature(method)
464
+ classtype = self.getClass()
465
+
466
+ # Check first parameter is 'cls'
467
+ params = list(sign.parameters.values())
468
+ if not params or params[0].name != "cls":
469
+ raise ReflectionAttributeError(f"The first (or only) argument of the method must be named 'cls' and must be of type {classtype}.")
470
+
471
+ # Get the expected type from the first parameter's annotation
472
+ annotation = params[0].annotation
473
+ if annotation != classtype:
474
+ raise ReflectionAttributeError(
475
+ f"The first argument has an incorrect annotation. Expected '{classtype}', but got '{annotation}'."
476
+ )
477
+
467
478
  # Handle private method name mangling
468
479
  if name.startswith("__") and not name.endswith("__"):
469
480
  class_name = self.getClassName()
@@ -474,7 +485,7 @@ class ReflectionInstance:
474
485
  raise ReflectionAttributeError(f"Attribute '{name}' already exists on '{self.getClassName()}'.")
475
486
 
476
487
  # Set the method on the instance
477
- setattr(self._instance, name, value)
488
+ setattr(self._instance.__class__, name, method)
478
489
 
479
490
  # Return True
480
491
  return True
@@ -495,7 +506,7 @@ class ReflectionInstance:
495
506
  """
496
507
  if not self.hasMethod(name):
497
508
  raise ReflectionAttributeError(f"Method '{name}' does not exist on '{self.getClassName()}'.")
498
- delattr(self._instance, name)
509
+ delattr(self._instance.__class__, name)
499
510
 
500
511
  def getMethodSignature(self, name: str) -> inspect.Signature:
501
512
  """
@@ -517,13 +528,34 @@ class ReflectionInstance:
517
528
  name = f"_{self.getClassName()}{name}"
518
529
 
519
530
  # Check if the method exists and is callable
520
- method = getattr(self._instance, name)
531
+ method = getattr(self._instance.__class__, name)
521
532
  if callable(method):
522
533
  return inspect.signature(method)
523
534
 
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.
@@ -541,7 +573,7 @@ class ReflectionInstance:
541
573
  class_methods = set()
542
574
  for name in dir(cls):
543
575
  attr = inspect.getattr_static(cls, name)
544
- if isinstance(attr, classmethod):
576
+ if isinstance(attr, (staticmethod, classmethod)):
545
577
  class_methods.add(name)
546
578
 
547
579
  # Collect public instance methods (not static, not class, not private/protected/magic)
@@ -590,9 +622,14 @@ class ReflectionInstance:
590
622
  List of protected method names
591
623
  """
592
624
  protected_methods = []
625
+ cls = self._instance.__class__
593
626
 
594
627
  # Collect protected instance methods (starting with a single underscore)
595
628
  for name, method in inspect.getmembers(self._instance, predicate=inspect.ismethod):
629
+ # Skip static and class methods
630
+ attr = inspect.getattr_static(cls, name)
631
+ if isinstance(attr, (staticmethod, classmethod)):
632
+ continue
596
633
  if name.startswith("_") and not name.startswith("__") and not name.startswith(f"_{self.getClassName()}"):
597
634
  protected_methods.append(name)
598
635
 
@@ -633,9 +670,13 @@ class ReflectionInstance:
633
670
  """
634
671
  class_name = self.getClassName()
635
672
  private_methods = []
673
+ cls = self._instance.__class__
636
674
 
637
675
  # Collect private instance methods (starting with class name)
638
676
  for name, method in inspect.getmembers(self._instance, predicate=inspect.ismethod):
677
+ attr = inspect.getattr_static(cls, name)
678
+ if isinstance(attr, (staticmethod, classmethod)):
679
+ continue
639
680
  if name.startswith(f"_{class_name}") and not name.startswith("__"):
640
681
  private_methods.append(name.replace(f"_{class_name}", ""))
641
682
 
@@ -653,7 +694,12 @@ class ReflectionInstance:
653
694
  """
654
695
  class_name = self.getClassName()
655
696
  private_methods = []
697
+ cls = self._instance.__class__
698
+
656
699
  for name, method in inspect.getmembers(self._instance, predicate=inspect.ismethod):
700
+ attr = inspect.getattr_static(cls, name)
701
+ if isinstance(attr, (staticmethod, classmethod)):
702
+ continue
657
703
  if name.startswith(f"_{class_name}") and not name.startswith("__"):
658
704
  # Remove the class name prefix for the returned name
659
705
  short_name = name.replace(f"_{class_name}", "")
@@ -672,7 +718,12 @@ class ReflectionInstance:
672
718
  """
673
719
  class_name = self.getClassName()
674
720
  private_methods = []
721
+ cls = self._instance.__class__
722
+
675
723
  for name, method in inspect.getmembers(self._instance, predicate=inspect.ismethod):
724
+ attr = inspect.getattr_static(cls, name)
725
+ if isinstance(attr, (staticmethod, classmethod)):
726
+ continue
676
727
  if name.startswith(f"_{class_name}") and not name.startswith("__"):
677
728
  # Remove the class name prefix for the returned name
678
729
  short_name = name.replace(f"_{class_name}", "")
@@ -680,20 +731,6 @@ class ReflectionInstance:
680
731
  private_methods.append(short_name)
681
732
  return private_methods
682
733
 
683
-
684
-
685
-
686
-
687
-
688
-
689
-
690
-
691
-
692
-
693
-
694
-
695
-
696
-
697
734
  def getPublicClassMethods(self) -> List[str]:
698
735
  """
699
736
  Get all class method names of the instance.
@@ -786,45 +823,78 @@ class ReflectionInstance:
786
823
  # Return the list of public asynchronous class method names
787
824
  return public_class_async_methods
788
825
 
826
+ def getProtectedClassMethods(self) -> List[str]:
827
+ """
828
+ Get all protected class method names of the instance.
789
829
 
830
+ Returns
831
+ -------
832
+ List[str]
833
+ List of protected class method names
834
+ """
835
+ cls = self._instance.__class__
836
+ class_methods = []
790
837
 
838
+ # Iterate over all attributes of the class
839
+ for name in dir(cls):
791
840
 
841
+ # Get the attribute using getattr_static to avoid triggering property getters
842
+ attr = inspect.getattr_static(cls, name)
792
843
 
844
+ # Check if the attribute is a class method
845
+ if isinstance(attr, classmethod):
793
846
 
847
+ # Check is a protected class method
848
+ if name.startswith(f"_") and not name.startswith("__") and not name.startswith(f"_{self.getClassName()}"):
849
+ class_methods.append(name)
794
850
 
851
+ # Return the list of public class method
852
+ return class_methods
795
853
 
854
+ def getProtectedClassSyncMethods(self) -> List[str]:
855
+ """
856
+ Get all protected synchronous class method names of the instance.
796
857
 
858
+ Returns
859
+ -------
860
+ List[str]
861
+ List of protected synchronous class method names
862
+ """
863
+ class_name = self.getClassName()
864
+ cls = self._instance.__class__
865
+ protected_class_sync_methods = []
797
866
 
867
+ # Iterate over all attributes of the class
868
+ for name in dir(cls):
798
869
 
870
+ # Get the attribute using getattr_static to avoid triggering property getters
871
+ attr = inspect.getattr_static(cls, name)
799
872
 
873
+ # Check if the attribute is a class method
874
+ if isinstance(attr, classmethod):
800
875
 
876
+ # Get the underlying function
877
+ func = attr.__func__
801
878
 
879
+ # Check if it's NOT a coroutine function (i.e., synchronous)
880
+ if not inspect.iscoroutinefunction(func) and name.startswith(f"_") and not name.startswith(f"_{class_name}"):
881
+ protected_class_sync_methods.append(str(name).replace(f"_{class_name}", ""))
802
882
 
883
+ # Return the list of protected class method names
884
+ return protected_class_sync_methods
803
885
 
804
-
805
-
806
-
807
-
808
-
809
-
810
-
811
-
812
-
813
-
814
-
815
-
816
- def getProtectedClassMethods(self) -> List[str]:
886
+ def getProtectedClassAsyncMethods(self) -> List[str]:
817
887
  """
818
- Get all protected class method names of the instance.
888
+ Get all protected asynchronous class method names of the instance.
819
889
 
820
890
  Returns
821
891
  -------
822
892
  List[str]
823
- List of protected class method names
893
+ List of protected asynchronous class method names
824
894
  """
825
895
  class_name = self.getClassName()
826
896
  cls = self._instance.__class__
827
- protected_class_methods = []
897
+ protected_class_async_methods = []
828
898
 
829
899
  # Iterate over all attributes of the class
830
900
  for name in dir(cls):
@@ -838,12 +908,12 @@ class ReflectionInstance:
838
908
  # Get the underlying function
839
909
  func = attr.__func__
840
910
 
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}", ""))
911
+ # Check if it's a coroutine function (i.e., asynchronous)
912
+ if inspect.iscoroutinefunction(func) and name.startswith(f"_") and not name.startswith(f"_{class_name}"):
913
+ protected_class_async_methods.append(str(name).replace(f"_{class_name}", ""))
844
914
 
845
- # Return the list of protected class method names
846
- return protected_class_methods
915
+ # Return the list of protected asynchronous class method names
916
+ return protected_class_async_methods
847
917
 
848
918
  def getPrivateClassMethods(self) -> List[str]:
849
919
  """
@@ -870,41 +940,25 @@ class ReflectionInstance:
870
940
  # Get the underlying function
871
941
  func = attr.__func__
872
942
 
873
- # Check if it's NOT a coroutine function (i.e., synchronous)
874
- if not inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
943
+ # Check if a private class method
944
+ if name.startswith(f"_{class_name}"):
875
945
  private_class_methods.append(str(name).replace(f"_{class_name}", ""))
876
946
 
877
947
  # Return the list of protected class method names
878
948
  return private_class_methods
879
949
 
880
-
881
-
882
-
883
-
884
-
885
-
886
-
887
-
888
-
889
-
890
-
891
-
892
-
893
-
894
-
895
-
896
- def getClassSyncMethods(self) -> List[str]:
950
+ def getPrivateClassSyncMethods(self) -> List[str]:
897
951
  """
898
- Get all synchronous class method names of the instance.
952
+ Get all private synchronous class method names of the instance.
899
953
 
900
954
  Returns
901
955
  -------
902
956
  List[str]
903
- List of synchronous class method names
957
+ List of private synchronous class method names
904
958
  """
905
959
  class_name = self.getClassName()
906
960
  cls = self._instance.__class__
907
- class_sync_methods = []
961
+ private_class_sync_methods = []
908
962
 
909
963
  # Iterate over all attributes of the class
910
964
  for name in dir(cls):
@@ -919,24 +973,24 @@ class ReflectionInstance:
919
973
  func = attr.__func__
920
974
 
921
975
  # 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}", ""))
976
+ if not inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
977
+ private_class_sync_methods.append(str(name).replace(f"_{class_name}", ""))
924
978
 
925
- # Return the list of synchronous class method names
926
- return class_sync_methods
979
+ # Return the list of private synchronous class method names
980
+ return private_class_sync_methods
927
981
 
928
- def getClassAsyncMethods(self) -> List[str]:
982
+ def getPrivateClassAsyncMethods(self) -> List[str]:
929
983
  """
930
- Get all asynchronous class method names of the instance.
984
+ Get all private asynchronous class method names of the instance.
931
985
 
932
986
  Returns
933
987
  -------
934
988
  List[str]
935
- List of asynchronous class method names
989
+ List of private asynchronous class method names
936
990
  """
937
991
  class_name = self.getClassName()
938
992
  cls = self._instance.__class__
939
- class_async_methods = []
993
+ private_class_async_methods = []
940
994
 
941
995
  # Iterate over all attributes of the class
942
996
  for name in dir(cls):
@@ -951,104 +1005,41 @@ class ReflectionInstance:
951
1005
  func = attr.__func__
952
1006
 
953
1007
  # 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
-
963
-
964
-
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]:
992
- """
993
- Get all dunder (double underscore) method names of the instance.
1008
+ if inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
1009
+ private_class_async_methods.append(str(name).replace(f"_{class_name}", ""))
994
1010
 
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
-
1011
+ # Return the list of private asynchronous class method names
1012
+ return private_class_async_methods
1021
1013
 
1022
- def getStaticMethods(self) -> List[str]:
1014
+ def getPublicStaticMethods(self) -> List[str]:
1023
1015
  """
1024
- Get all static method names of the instance.
1016
+ Get public static method names of the instance.
1025
1017
 
1026
1018
  Returns
1027
1019
  -------
1028
1020
  List[str]
1029
1021
  List of static method names
1030
1022
  """
1031
- class_name = self.getClassName()
1032
1023
  cls = self._instance.__class__
1033
1024
  static_methods = []
1034
1025
  for name in dir(cls):
1035
1026
  attr = inspect.getattr_static(cls, name)
1036
- if isinstance(attr, staticmethod):
1037
- static_methods.append(str(name).replace(f"_{class_name}", ""))
1027
+ if isinstance(attr, staticmethod) and not name.startswith(f"_"):
1028
+ static_methods.append(name)
1038
1029
  return static_methods
1039
1030
 
1040
- def getStaticSyncMethods(self) -> List[str]:
1031
+ def getPublicStaticSyncMethods(self) -> List[str]:
1041
1032
  """
1042
- Get all synchronous static method names of the instance.
1033
+ Get all public synchronous static method names of the instance.
1043
1034
 
1044
1035
  Returns
1045
1036
  -------
1046
1037
  List[str]
1047
- List of synchronous static method names
1038
+ List of public synchronous static method names
1048
1039
  """
1049
1040
  class_name = self.getClassName()
1050
1041
  cls = self._instance.__class__
1051
- static_sync_methods = []
1042
+ public_static_sync_methods = []
1052
1043
 
1053
1044
  # Iterate over all attributes of the class
1054
1045
  for name in dir(cls):
@@ -1063,24 +1054,24 @@ class ReflectionInstance:
1063
1054
  func = attr.__func__
1064
1055
 
1065
1056
  # 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}", ""))
1057
+ if not inspect.iscoroutinefunction(func) and not name.startswith(f"_"):
1058
+ public_static_sync_methods.append(str(name).replace(f"_{class_name}", ""))
1068
1059
 
1069
- # Return the list of synchronous static method names
1070
- return static_sync_methods
1060
+ # Return the list of public synchronous static method names
1061
+ return public_static_sync_methods
1071
1062
 
1072
- def getStaticAsyncMethods(self) -> List[str]:
1063
+ def getPublicStaticAsyncMethods(self) -> List[str]:
1073
1064
  """
1074
- Get all asynchronous static method names of the instance.
1065
+ Get all public asynchronous static method names of the instance.
1075
1066
 
1076
1067
  Returns
1077
1068
  -------
1078
1069
  List[str]
1079
- List of asynchronous static method names
1070
+ List of public asynchronous static method names
1080
1071
  """
1081
1072
  class_name = self.getClassName()
1082
1073
  cls = self._instance.__class__
1083
- static_async_methods = []
1074
+ public_static_async_methods = []
1084
1075
 
1085
1076
  # Iterate over all attributes of the class
1086
1077
  for name in dir(cls):
@@ -1095,312 +1086,374 @@ class ReflectionInstance:
1095
1086
  func = attr.__func__
1096
1087
 
1097
1088
  # 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
-
1089
+ if inspect.iscoroutinefunction(func) and not name.startswith(f"_"):
1090
+ public_static_async_methods.append(str(name).replace(f"_{class_name}", ""))
1189
1091
 
1092
+ # Return the list of public asynchronous static method names
1093
+ return public_static_async_methods
1190
1094
 
1095
+ def getProtectedStaticMethods(self) -> List[str]:
1096
+ """
1097
+ Get all protected static method names of the instance.
1191
1098
 
1099
+ Returns
1100
+ -------
1101
+ List[str]
1102
+ List of protected static method names
1103
+ """
1104
+ cls = self._instance.__class__
1105
+ protected_static_methods = []
1192
1106
 
1107
+ # Iterate over all attributes of the class
1108
+ for name in dir(cls):
1193
1109
 
1110
+ # Get the attribute using getattr_static to avoid triggering property getters
1111
+ attr = inspect.getattr_static(cls, name)
1194
1112
 
1113
+ # Check if the attribute is a static method
1114
+ if isinstance(attr, staticmethod) and name.startswith(f"_") and not name.startswith("__") and not name.startswith(f"_{self.getClassName()}"):
1115
+ protected_static_methods.append(name)
1195
1116
 
1117
+ return protected_static_methods
1196
1118
 
1119
+ def getProtectedStaticSyncMethods(self) -> List[str]:
1120
+ """
1121
+ Get all protected synchronous static method names of the instance.
1197
1122
 
1123
+ Returns
1124
+ -------
1125
+ List[str]
1126
+ List of protected synchronous static method names
1127
+ """
1128
+ class_name = self.getClassName()
1129
+ cls = self._instance.__class__
1130
+ protected_static_sync_methods = []
1198
1131
 
1132
+ # Iterate over all attributes of the class
1133
+ for name in dir(cls):
1199
1134
 
1135
+ # Get the attribute using getattr_static to avoid triggering property getters
1136
+ attr = inspect.getattr_static(cls, name)
1200
1137
 
1138
+ # Check if the attribute is a static method
1139
+ if isinstance(attr, staticmethod):
1201
1140
 
1141
+ # Get the underlying function
1142
+ func = attr.__func__
1202
1143
 
1144
+ # Check if it's NOT a coroutine function (i.e., synchronous)
1145
+ if not inspect.iscoroutinefunction(func) and name.startswith(f"_") and not name.startswith(f"_{class_name}"):
1146
+ protected_static_sync_methods.append(str(name).replace(f"_{class_name}", ""))
1203
1147
 
1148
+ return protected_static_sync_methods
1204
1149
 
1150
+ def getProtectedStaticAsyncMethods(self) -> List[str]:
1151
+ """
1152
+ Get all protected asynchronous static method names of the instance.
1205
1153
 
1154
+ Returns
1155
+ -------
1156
+ List[str]
1157
+ List of protected asynchronous static method names
1158
+ """
1159
+ class_name = self.getClassName()
1160
+ cls = self._instance.__class__
1161
+ protected_static_async_methods = []
1206
1162
 
1163
+ # Iterate over all attributes of the class
1164
+ for name in dir(cls):
1207
1165
 
1166
+ # Get the attribute using getattr_static to avoid triggering property getters
1167
+ attr = inspect.getattr_static(cls, name)
1208
1168
 
1169
+ # Check if the attribute is a static method
1170
+ if isinstance(attr, staticmethod):
1209
1171
 
1172
+ # Get the underlying function
1173
+ func = attr.__func__
1210
1174
 
1175
+ # Check if it's a coroutine function (i.e., asynchronous)
1176
+ if inspect.iscoroutinefunction(func) and name.startswith(f"_") and not name.startswith(f"_{class_name}"):
1177
+ protected_static_async_methods.append(str(name).replace(f"_{class_name}", ""))
1211
1178
 
1179
+ return protected_static_async_methods
1212
1180
 
1181
+ def getPrivateStaticMethods(self) -> List[str]:
1182
+ """
1183
+ Get all private static method names of the instance.
1213
1184
 
1185
+ Returns
1186
+ -------
1187
+ List[str]
1188
+ List of private static method names
1189
+ """
1190
+ class_name = self.getClassName()
1191
+ cls = self._instance.__class__
1192
+ private_static_methods = []
1214
1193
 
1194
+ # Iterate over all attributes of the class
1195
+ for name in dir(cls):
1215
1196
 
1197
+ # Get the attribute using getattr_static to avoid triggering property getters
1198
+ attr = inspect.getattr_static(cls, name)
1216
1199
 
1200
+ # Check if the attribute is a static method
1201
+ if isinstance(attr, staticmethod):
1217
1202
 
1203
+ # Check if a private static method
1204
+ if name.startswith(f"_{class_name}"):
1205
+ private_static_methods.append(str(name).replace(f"_{class_name}", ""))
1218
1206
 
1207
+ return private_static_methods
1219
1208
 
1209
+ def getPrivateStaticSyncMethods(self) -> List[str]:
1210
+ """
1211
+ Get all private synchronous static method names of the instance.
1220
1212
 
1213
+ Returns
1214
+ -------
1215
+ List[str]
1216
+ List of private synchronous static method names
1217
+ """
1218
+ class_name = self.getClassName()
1219
+ cls = self._instance.__class__
1220
+ private_static_sync_methods = []
1221
1221
 
1222
+ # Iterate over all attributes of the class
1223
+ for name in dir(cls):
1222
1224
 
1225
+ # Get the attribute using getattr_static to avoid triggering property getters
1226
+ attr = inspect.getattr_static(cls, name)
1223
1227
 
1228
+ # Check if the attribute is a static method
1229
+ if isinstance(attr, staticmethod):
1224
1230
 
1231
+ # Get the underlying function
1232
+ func = attr.__func__
1225
1233
 
1234
+ # Check if it's NOT a coroutine function (i.e., synchronous)
1235
+ if not inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
1236
+ private_static_sync_methods.append(str(name).replace(f"_{class_name}", ""))
1226
1237
 
1238
+ return private_static_sync_methods
1227
1239
 
1240
+ def getPrivateStaticAsyncMethods(self) -> List[str]:
1241
+ """
1242
+ Get all private asynchronous static method names of the instance.
1228
1243
 
1244
+ Returns
1245
+ -------
1246
+ List[str]
1247
+ List of private asynchronous static method names
1248
+ """
1249
+ class_name = self.getClassName()
1250
+ cls = self._instance.__class__
1251
+ private_static_async_methods = []
1229
1252
 
1253
+ # Iterate over all attributes of the class
1254
+ for name in dir(cls):
1230
1255
 
1256
+ # Get the attribute using getattr_static to avoid triggering property getters
1257
+ attr = inspect.getattr_static(cls, name)
1231
1258
 
1259
+ # Check if the attribute is a static method
1260
+ if isinstance(attr, staticmethod):
1232
1261
 
1262
+ # Get the underlying function
1263
+ func = attr.__func__
1233
1264
 
1265
+ # Check if it's a coroutine function (i.e., asynchronous)
1266
+ if inspect.iscoroutinefunction(func) and name.startswith(f"_{class_name}"):
1267
+ private_static_async_methods.append(str(name).replace(f"_{class_name}", ""))
1234
1268
 
1269
+ return private_static_async_methods
1235
1270
 
1271
+ def getDunderMethods(self) -> List[str]:
1272
+ """
1273
+ Get all dunder (double underscore) method names of the instance.
1236
1274
 
1275
+ Returns
1276
+ -------
1277
+ List[str]
1278
+ List of dunder method names
1279
+ """
1280
+ dunder_methods = []
1281
+ exclude = []
1237
1282
 
1283
+ # Collect dunder methods (starting and ending with double underscores)
1284
+ for name in dir(self._instance):
1285
+ if name in exclude:
1286
+ continue
1287
+ if name.startswith("__") and name.endswith("__"):
1288
+ dunder_methods.append(name)
1238
1289
 
1290
+ return dunder_methods
1239
1291
 
1292
+ def getMagicMethods(self) -> List[str]:
1293
+ """
1294
+ Get all magic method names of the instance.
1240
1295
 
1296
+ Returns
1297
+ -------
1298
+ List[str]
1299
+ List of magic method names
1300
+ """
1301
+ return self.getDunderMethods()
1241
1302
 
1303
+ def getProperties(self) -> List:
1304
+ """
1305
+ Get all properties of the instance.
1242
1306
 
1307
+ Returns
1308
+ -------
1309
+ List[str]
1310
+ List of property names
1311
+ """
1243
1312
 
1313
+ properties = []
1314
+ for name, prop in self._instance.__class__.__dict__.items():
1315
+ if isinstance(prop, property):
1316
+ name_prop = name.replace(f"_{self.getClassName()}", "")
1317
+ properties.append(name_prop)
1318
+ return properties
1244
1319
 
1320
+ def getPublicProperties(self) -> List:
1321
+ """
1322
+ Get all public properties of the instance.
1245
1323
 
1324
+ Returns
1325
+ -------
1326
+ List:
1327
+ List of public property names and their values
1328
+ """
1329
+ properties = []
1330
+ cls_name = self.getClassName()
1331
+ for name, prop in self._instance.__class__.__dict__.items():
1332
+ if isinstance(prop, property):
1333
+ if not name.startswith(f"_") and not name.startswith(f"_{cls_name}"):
1334
+ properties.append(name.replace(f"_{cls_name}", ""))
1335
+ return properties
1246
1336
 
1247
- def getProperties(self) -> Dict[str, ClassProperty]:
1337
+ def getProtectedProperties(self) -> List:
1248
1338
  """
1249
- Get all properties of the instance.
1339
+ Get all protected properties of the instance.
1250
1340
 
1251
1341
  Returns
1252
1342
  -------
1253
- List[str]
1254
- List of property names
1343
+ List
1344
+ List of protected property names and their values
1255
1345
  """
1256
-
1257
- properties = {}
1346
+ properties = []
1258
1347
  for name, prop in self._instance.__class__.__dict__.items():
1259
1348
  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
- )
1349
+ if name.startswith(f"_") and not name.startswith("__") and not name.startswith(f"_{self.getClassName()}"):
1350
+ properties.append(name)
1266
1351
  return properties
1267
1352
 
1268
- def getPropertyNames(self) -> List[str]:
1353
+ def getPrivateProperties(self) -> List:
1269
1354
  """
1270
- Get all property names of the instance.
1355
+ Get all private properties of the instance.
1271
1356
 
1272
1357
  Returns
1273
1358
  -------
1274
- List[str]
1275
- List of property names
1359
+ List
1360
+ List of private property names and their values
1276
1361
  """
1277
- return self.getProperties().keys()
1362
+ properties = []
1363
+ for name, prop in self._instance.__class__.__dict__.items():
1364
+ if isinstance(prop, property):
1365
+ if name.startswith(f"_{self.getClassName()}") and not name.startswith("__"):
1366
+ properties.append(name.replace(f"_{self.getClassName()}", ""))
1367
+ return properties
1278
1368
 
1279
- def getProperty(self, property_name: str) -> Any:
1369
+ def getPropierty(self, name: str) -> Any:
1280
1370
  """
1281
- Get the value of a property.
1371
+ Get a specific property of the instance.
1282
1372
 
1283
1373
  Parameters
1284
1374
  ----------
1285
- property_name : str
1286
- Name of the property
1375
+ name : str
1376
+ The name of the property to retrieve
1287
1377
 
1288
1378
  Returns
1289
1379
  -------
1290
- Any
1291
- The value of the property
1380
+ ClassProperty
1381
+ The value of the specified property
1292
1382
 
1293
1383
  Raises
1294
1384
  ------
1295
- AttributeError
1296
- If the property doesn't exist or is not a property
1385
+ ReflectionAttributeError
1386
+ If the property does not exist or is not accessible
1297
1387
  """
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
1388
+ # Check if the property name is valid
1389
+ if name in self.getProperties():
1390
+
1391
+ # Handle private property name mangling
1392
+ if name.startswith("__") and not name.endswith("__"):
1393
+ class_name = self.getClassName()
1394
+ name = f"_{class_name}{name}"
1395
+
1396
+ # Return the property value from the instance
1397
+ return getattr(self._instance, name, None)
1302
1398
 
1303
- def getPropertySignature(self, property_name: str) -> inspect.Signature:
1399
+ # If the property does not exist, raise an error
1400
+ raise ReflectionAttributeError(f"Property '{name}' does not exist on '{self.getClassName()}'.")
1401
+
1402
+ def getPropertySignature(self, name: str) -> inspect.Signature:
1304
1403
  """
1305
1404
  Get the signature of a property.
1306
1405
 
1307
1406
  Parameters
1308
1407
  ----------
1309
- property_name : str
1408
+ name : str
1310
1409
  Name of the property
1311
1410
 
1312
1411
  Returns
1313
1412
  -------
1314
1413
  inspect.Signature
1315
1414
  The property signature
1316
-
1317
- Raises
1318
- ------
1319
- AttributeError
1320
- If the property doesn't exist or is not a property
1321
1415
  """
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
1416
+ # Handle private property name mangling
1417
+ original_name = name
1418
+ if name.startswith("__") and not name.endswith("__"):
1419
+ class_name = self.getClassName()
1420
+ name = f"_{class_name}{name}"
1421
+
1422
+ # Check if the property exists
1423
+ prop = getattr(self._instance.__class__, name, None)
1424
+ if isinstance(prop, property):
1425
+ return inspect.signature(prop.fget)
1426
+
1427
+ # If the property does not exist, raise an error
1428
+ raise ReflectionAttributeError(f"Property '{original_name}' does not exist on '{self.getClassName()}'.")
1326
1429
 
1327
- def getPropertyDoc(self, property_name: str) -> str:
1430
+ def getPropiertyDocstring(self, name: str) -> str:
1328
1431
  """
1329
1432
  Get the docstring of a property.
1330
1433
 
1331
1434
  Parameters
1332
1435
  ----------
1333
- property_name : str
1436
+ name : str
1334
1437
  Name of the property
1335
1438
 
1336
1439
  Returns
1337
1440
  -------
1338
1441
  str
1339
1442
  The docstring of the property
1340
-
1341
- Raises
1342
- ------
1343
- AttributeError
1344
- If the property doesn't exist or is not a property
1345
1443
  """
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
-
1444
+ # Handle private property name mangling
1445
+ original_name = name
1446
+ if name.startswith("__") and not name.endswith("__"):
1447
+ class_name = self.getClassName()
1448
+ name = f"_{class_name}{name}"
1401
1449
 
1402
-
1450
+ # Check if the property exists
1451
+ prop = getattr(self._instance.__class__, name, None)
1452
+ if isinstance(prop, property):
1453
+ return prop.fget.__doc__ or ""
1403
1454
 
1455
+ # If the property does not exist, raise an error
1456
+ raise ReflectionAttributeError(f"Property '{original_name}' does not exist on '{self.getClassName()}'.")
1404
1457
 
1405
1458
  def getConstructorDependencies(self) -> ClassDependency:
1406
1459
  """
@@ -1433,4 +1486,15 @@ class ReflectionInstance:
1433
1486
  - resolved: Dictionary of resolved dependencies with their names and values.
1434
1487
  - unresolved: List of unresolved dependencies (parameter names without default values or annotations).
1435
1488
  """
1436
- return ReflectDependencies(self._instance).getMethodDependencies(method_name)
1489
+
1490
+ # Ensure the method name is a valid identifier
1491
+ if not self.hasMethod(method_name):
1492
+ raise ReflectionAttributeError(f"Method '{method_name}' does not exist on '{self.getClassName()}'.")
1493
+
1494
+ # Handle private method name mangling
1495
+ if method_name.startswith("__") and not method_name.endswith("__"):
1496
+ class_name = self.getClassName()
1497
+ method_name = f"_{class_name}{method_name}"
1498
+
1499
+ # Use ReflectDependencies to get method dependencies
1500
+ return ReflectDependencies(self._instance).getMethodDependencies(method_name)