-
Notifications
You must be signed in to change notification settings - Fork 226
Expand file tree
/
Copy pathPyDataDescr.java
More file actions
147 lines (126 loc) · 4.19 KB
/
PyDataDescr.java
File metadata and controls
147 lines (126 loc) · 4.19 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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package org.python.core;
import org.python.expose.ExposedGet;
import org.python.expose.ExposedMethod;
import org.python.expose.ExposedType;
/**
* Implements type checking and return type coercion for a data descriptor. A
* subclass must at least implement invokeGet which is called in __get__
* operations. If the descriptor supports setting and deleting, the subclass
* must also override invokeSet and invokeDel respectively. When implementing
* those methods, their respective implementsDescr* methods should be overriden
* as well.
*/
@Untraversable
@ExposedType(name = "getset_descriptor", base = PyObject.class, isBaseType = false)
public abstract class PyDataDescr extends PyDescriptor {
protected Class ofType;
private String doc;
/**
* @param onType -
* the type the descriptor belongs to
* @param name -
* the name of the descriptor on descriptor type
* @param ofType -
* the type returned by the descriptor
*/
public PyDataDescr(PyType onType, String name, Class ofType, String doc) {
this(name, ofType, doc);
setType(onType);
}
/**
* This constructor does not initialize the type the descriptor belongs to. setType must be
* called before this descriptor can be used.
*
* @param name -
* the name of the descriptor on descriptor type
* @param ofType -
* the type returned by the descriptor
*/
public PyDataDescr(String name, Class ofType, String doc) {
this.name = name;
this.ofType = ofType;
this.doc = doc;
}
/**
* Sets the type the descriptor belongs to.
*/
public void setType(PyType onType) {
dtype = onType;
}
@Override
public PyObject __get__(PyObject obj, PyObject type) {
return getset_descriptor___get__(obj, type);
}
@ExposedMethod(defaults = "null")
public PyObject getset_descriptor___get__(PyObject obj, PyObject type) {
if(obj != null) {
checkGetterType(obj.getType());
return Py.java2py(invokeGet(obj));
}
return this;
}
public abstract Object invokeGet(PyObject obj);
@Override
public void __set__(PyObject obj, PyObject value) {
getset_descriptor___set__(obj, value);
}
@ExposedMethod
public void getset_descriptor___set__(PyObject obj, PyObject value) {
checkGetterType(obj.getType());
// XXX: We may want to special case value being PyUnicode and ofType being String
// (then explicitly value.encode() first)
Object converted = value.__tojava__(ofType);
if(converted == Py.NoConversion) {
throw Py.TypeError(String.format("unsupported type for assignment to %s: '%.200s'",
name, value.getType().fastGetName()));
}
invokeSet(obj, converted);
}
public void invokeSet(PyObject obj, Object converted) {
throw new UnsupportedOperationException("Must be overriden by a subclass");
}
@Override
public void __delete__(PyObject obj) {
getset_descriptor___delete__(obj);
}
@ExposedMethod
public void getset_descriptor___delete__(PyObject obj) {
if(obj != null) {
checkGetterType(obj.getType());
invokeDelete(obj);
}
}
public void invokeDelete(PyObject obj) {
throw new UnsupportedOperationException("Must be overriden by a subclass");
}
@Override
public boolean isDataDescr() {
return true;
}
@Override
public String toString() {
return String.format("<attribute '%s' of '%s' objects>", name, dtype.fastGetName());
}
@ExposedGet(name = "__doc__")
public String getDoc() {
return doc;
}
/**
* Return the name this descriptor is exposed as.
*
* @return a name String
*/
@ExposedGet(name = "__name__")
public String getName() {
return name;
}
/**
* Return the owner class of this descriptor.
*
* @return this descriptor's owner
*/
@ExposedGet(name = "__objclass__")
public PyObject getObjClass() {
return dtype;
}
}