1
|
|
|
"""Descriptor Inspector. |
2
|
|
|
|
3
|
|
|
Wrapper around objects, helps expose descriptor protocol. |
4
|
|
|
|
5
|
|
|
""" |
6
|
|
|
|
7
|
6 |
|
from .flags import ENABLE_SET_NAME |
8
|
6 |
|
from .inspector import _Inspector |
9
|
|
|
|
10
|
|
|
|
11
|
6 |
|
class DescriptorInspector(_Inspector): |
12
|
|
|
|
13
|
|
|
"""Wrapper around objects. Provides access to descriptor protocol.""" |
14
|
|
|
|
15
|
6 |
|
__slots__ = () |
16
|
|
|
|
17
|
6 |
|
def __new__(cls, obj): |
18
|
6 |
|
return super().__new__(cls, obj, mro=type(obj).__mro__) |
19
|
|
|
|
20
|
6 |
|
@property |
21
|
|
|
def has_get(self): |
22
|
|
|
"""Return whether self.object's mro provides __get__.""" |
23
|
6 |
|
return '__get__' in self.dict |
24
|
|
|
|
25
|
6 |
|
@property |
26
|
|
|
def has_set(self): |
27
|
|
|
"""Return whether self.object's mro provides __set__.""" |
28
|
6 |
|
return '__set__' in self.dict |
29
|
|
|
|
30
|
6 |
|
@property |
31
|
|
|
def has_delete(self): |
32
|
|
|
"""Return whether self.object's mro provides __delete__.""" |
33
|
6 |
|
return '__delete__' in self.dict |
34
|
|
|
|
35
|
6 |
|
if ENABLE_SET_NAME: |
36
|
2 |
|
@property |
37
|
|
|
def has_set_name(self): |
38
|
|
|
"""Return whether self.object's mro provides __set_name__.""" |
39
|
2 |
|
return '__set_name__' in self.dict |
40
|
|
|
|
41
|
2 |
|
def set_name(self, owner, name): |
42
|
|
|
"""Call __set_name__, bypassing descriptor protocol.""" |
43
|
2 |
|
self.get_as_attribute('__set_name__')(self.object, owner, name) |
44
|
|
|
|
45
|
2 |
|
@property |
46
|
|
|
def has_non_data(self): |
47
|
|
|
"""Return whether self.object's mro provides non-data methods.""" |
48
|
2 |
|
return self.has_get or self.has_set_name |
49
|
|
|
else: |
50
|
4 |
|
has_non_data = has_get |
51
|
|
|
|
52
|
6 |
|
@property |
53
|
|
|
def is_data(self): |
54
|
|
|
"""Return whether self.object is a data descriptor.""" |
55
|
6 |
|
return self.has_set or self.has_delete |
56
|
|
|
|
57
|
|
|
# I guess I don't actually have a use for this property? |
58
|
6 |
|
@property |
59
|
|
|
def is_non_data(self): |
60
|
|
|
"""Return whether self.object is a non-data descriptor.""" |
61
|
|
|
return self.has_non_data and not self.is_data |
62
|
|
|
|
63
|
6 |
|
@property |
64
|
|
|
def is_descriptor(self): |
65
|
|
|
"""Return whether self.object is a descriptor.""" |
66
|
6 |
|
return self.has_non_data or self.is_data |
67
|
|
|
|
68
|
6 |
|
def get(self, instance, owner): |
69
|
|
|
"""Return the result of __get__, bypassing descriptor protocol.""" |
70
|
6 |
|
return self.get_as_attribute('__get__')(self.object, instance, owner) |
71
|
|
|
|
72
|
6 |
|
def set(self, instance, value): |
73
|
|
|
"""Call __set__, bypassing descriptor protocol.""" |
74
|
6 |
|
self.get_as_attribute('__set__')(self.object, instance, value) |
75
|
|
|
|
76
|
6 |
|
def delete(self, instance): |
77
|
|
|
"""Call __delete__, bypassing descriptor protocol.""" |
78
|
|
|
self.get_as_attribute('__delete__')(self.object, instance) |
79
|
|
|
|