-
Notifications
You must be signed in to change notification settings - Fork 1
/
type.py
78 lines (55 loc) · 2.56 KB
/
type.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import inspect
from types import MethodWrapperType
class _ObjInfoType:
""" Only one of these methods starting with 'is_' will return True. """
def type(self, nice_output=False):
""" Get a string of what type obj is.
:param generallibrary.ObjInfo self:
:param nice_output: """
types = [name for name, method in self.type_methods.items() if method(self)]
# if len(types) != 1:
# raise AssertionError(f"{self.obj} does not have one type: {types}")
return_type = types[0] if types else None
if nice_output and return_type is not None:
return return_type.split("_")[1].capitalize()
return return_type
def is_module(self):
""" Get whether obj is a module.
:param generallibrary.ObjInfo self: """
return inspect.ismodule(self.obj)
def is_function(self):
""" Get whether obj is a function.
:param generallibrary.ObjInfo self: """
return (inspect.isfunction(self.obj) or inspect.isbuiltin(self.obj)) and not self.is_method()
def is_class(self):
""" Get whether obj is a class.
:param generallibrary.ObjInfo self: """
return inspect.isclass(self.obj)
@staticmethod
def _is_property(obj):
return hasattr(obj, "fget")
def is_property(self):
""" Get whether obj is a property of a class.
:param generallibrary.ObjInfo self: """
return self._is_property(self.obj)
def is_instance(self):
""" Get whether obj is an instance of it's class.
I think every obj is technically an instance of something though.
:param generallibrary.ObjInfo self: """
if getattr(self.obj, "__name__", None) == "__weakref__": # Edge case
return True
return not hasattr(self.obj, "__name__") and not self.is_property() and not self.is_method()
def is_method(self):
""" Get whether obj is a method of a class.
:param generallibrary.ObjInfo self: """
if inspect.ismethod(self.obj) or inspect.ismethoddescriptor(self.obj):
return True
if self.is_class() or not callable(self.obj): # Unbound cls and static methods aren't "callable"
return False
if isinstance(self.obj, MethodWrapperType):
return True
if parent := self.get_parent():
if parent.is_class():
return True
return False
type_methods = {key: value for key, value in locals().items() if key != "type" and not key.startswith("_")}