Skip to content

Commit 0db9232

Browse files
committed
-
1 parent 5214f2c commit 0db9232

File tree

1 file changed

+11
-27
lines changed

1 file changed

+11
-27
lines changed

source_py3/python_toolbox/misc_tools/proxy_property.py

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
import re
1111

12-
simple_case_pattern = re.compile(r'''([A-Za-z0-9_]+\.?)+''')
13-
1412

1513
class ProxyProperty:
1614
'''
@@ -60,38 +58,24 @@ def __init__(self, attribute_name, doc=None):
6058
raise Exception("The `attribute_name` must start with a dot to "
6159
"make it clear it's an attribute. %s does not "
6260
"start with a dot." % repr(attribute_name))
61+
self.getter = self.setter = None
62+
exec('def getter(thing): return thing%s' % attribute_name, globals(), locals())
63+
exec('def setter(thing, value): thing%s = value' % attribute_name)
64+
exec('self.getter, self.setter = getter, setter')
6365
self.attribute_name = attribute_name[1:]
6466
self.__doc__ = doc
6567

6668

67-
def __get__(self, obj, our_type=None):
68-
if obj is None:
69+
def __get__(self, thing, our_type=None):
70+
if thing is None:
6971
# We're being accessed from the class itself, not from an object
7072
return self
7173
else:
72-
if simple_case_pattern.match(self.attribute_name):
73-
current_object = obj
74-
for attribute_name in self.attribute_name.split('.'):
75-
current_object = getattr(current_object, attribute_name)
76-
return current_object
77-
else:
78-
from python_toolbox import address_tools
79-
return address_tools.resolve('obj.%s' % self.attribute_name,
80-
namespace={'obj': obj})
81-
82-
def __set__(self, obj, value):
74+
return self.getter(thing)
8375

84-
# todo: should I check if `obj` is `None` and set on class? Same for
76+
def __set__(self, thing, value):
77+
# todo: should I check if `thing` is `None` and set on class? Same for
8578
# `__delete__`?
8679

87-
if simple_case_pattern.match(self.attribute_name):
88-
current_object = obj
89-
for attribute_name in self.attribute_name.split('.')[:-1]:
90-
current_object = getattr(current_object, attribute_name)
91-
setattr(current_object, self.attribute_name.split('.')[-1], value)
92-
else:
93-
from python_toolbox import address_tools
94-
left_segment, right_segment = self.attribute_name.rsplit('.', 1)
95-
deepest_object = address_tools.resolve('obj.%s' % left_segment,
96-
namespace={'obj': obj})
97-
setattr(deepest_object, right_segment, value)
80+
return self.setter(thing, value)
81+

0 commit comments

Comments
 (0)