Repository navigation
Expand file tree
/
Copy pathdescrip.py
More file actions
61 lines (46 loc) · 1.59 KB
/
Copy pathdescrip.py
File metadata and controls
61 lines (46 loc) · 1.59 KB
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
class Descriptor(object):
def __init__(self, name):
self.name = name
def __get__(self, instance, cls):
print('%s:__get__' % self.name)
return instance.__dict__[self.name]
def __set__(self, instance, value):
print('%s:__set__ %s' % (self.name, value))
instance.__dict__[self.name] = value
def __delete__(self, instance):
print('%s:__delete__' % self.name)
class Typed(Descriptor):
expected_type = None
def __init__(self,name):
self.name = name
def __get__(self,obj,cls):
if obj is None:
return self
else:
return obj.__dict__[self.name]
def __set__(self,obj,value):
if not isinstance(value,self.expected_type):
raise TypeError("Expected %s" % self.expected_type)
super(Typed, self).__set__(obj, value)
def __delete__(self,obj):
raise AttributeError("Can't delete")
class Integer(Typed):
expected_type = int
class Float(Typed):
expected_type = (float, int)
class String(Typed):
expected_type = str
def typecheck(**kwargs):
def decorate(cls):
for field, val_type in kwargs.items():
setattr(cls, field, val_type(field))
return cls
return decorate
class typedmeta(type):
def __new__(cls, class_name, bases, methods):
for key, value in methods.items():
if isinstance(value, type) and issubclass(value, Typed):
methods[key] = value(key)
return type.__new__(cls, class_name, bases, methods)
class typedobject(metaclass=typedmeta):
pass