Skip to content

Commit 5502077

Browse files
committed
add support for specifying docstrings in ExposedType/ExposedGet annotations.
exposed type.__doc__, which for the most part removes the need for PyObject.getDoc
1 parent 69b7085 commit 5502077

25 files changed

Lines changed: 147 additions & 107 deletions

src/org/python/core/PyBuiltinCallable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public PyObject fastGetName() {
3030
}
3131

3232
@ExposedGet(name = "__doc__")
33-
public String fastGetDoc() {
33+
public String getDoc() {
3434
return doc;
3535
}
3636

src/org/python/core/PyDataDescr.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public abstract class PyDataDescr extends PyDescriptor {
1717

1818
protected Class ofType;
1919

20+
private String doc;
21+
2022
/**
2123
* @param onType -
2224
* the type the descriptor belongs to
@@ -25,8 +27,8 @@ public abstract class PyDataDescr extends PyDescriptor {
2527
* @param ofType -
2628
* the type returned by the descriptor
2729
*/
28-
public PyDataDescr(PyType onType, String name, Class ofType) {
29-
this(name, ofType);
30+
public PyDataDescr(PyType onType, String name, Class ofType, String doc) {
31+
this(name, ofType, doc);
3032
setType(onType);
3133
}
3234

@@ -39,9 +41,10 @@ public PyDataDescr(PyType onType, String name, Class ofType) {
3941
* @param ofType -
4042
* the type returned by the descriptor
4143
*/
42-
public PyDataDescr(String name, Class ofType) {
44+
public PyDataDescr(String name, Class ofType, String doc) {
4345
this.name = name;
4446
this.ofType = ofType;
47+
this.doc = doc;
4548
}
4649

4750
/**
@@ -116,6 +119,11 @@ public String toString() {
116119
return String.format("<attribute '%s' of '%s' objects>", name, dtype.fastGetName());
117120
}
118121

122+
@ExposedGet(name = "__doc__")
123+
public String getDoc() {
124+
return doc;
125+
}
126+
119127
/**
120128
* Return the name this descriptor is exposed as.
121129
*

src/org/python/core/PyFunction.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,6 @@ final void function___setattr__(String name, PyObject value) {
283283
super.__setattr__(name, value);
284284
}
285285

286-
@Override
287-
public PyObject getDoc() {
288-
return __doc__;
289-
}
290-
291286
@Override
292287
public PyObject __get__(PyObject obj, PyObject type) {
293288
return function___get__(obj, type);

src/org/python/core/PyMethod.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,9 @@ public int hashCode() {
285285
return hashCode ^ im_func.hashCode();
286286
}
287287

288-
@Override
288+
@ExposedGet(name = "__doc__")
289289
public PyObject getDoc() {
290-
return im_func.getDoc();
290+
return im_func.__getattr__("__doc__");
291291
}
292292

293293
@Override

src/org/python/core/PyMethodDescr.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public PyMethodDescr(PyType t, PyBuiltinCallable func) {
2121
}
2222

2323
@ExposedGet(name = "__doc__")
24-
public String fastGetDoc() {
25-
return meth.fastGetDoc();
24+
public String getDoc() {
25+
return meth.getDoc();
2626
}
2727

2828
public int getMaxargs() {

src/org/python/core/PyModule.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,6 @@ public void delDict() {
8080
throw Py.TypeError("readonly attribute");
8181
}
8282

83-
@ExposedGet(name = "__doc__")
84-
public PyObject getDoc() {
85-
PyObject dict = fastGetDict();
86-
if (dict != null) {
87-
PyObject doc = dict.__finditem__("__doc__");
88-
if (doc != null) {
89-
return doc;
90-
}
91-
}
92-
return moduleDoc;
93-
}
94-
9583
protected PyObject impAttr(String name) {
9684
PyObject path = __dict__.__finditem__("__path__");
9785
PyObject pyName = __dict__.__finditem__("__name__");

src/org/python/core/PyObject.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,6 @@ public PyObject fastGetClass() {
111111
return objtype;
112112
}
113113

114-
//XXX: needs doc
115-
@ExposedGet(name = "__doc__")
116-
public PyObject getDoc() {
117-
PyObject d = fastGetDict();
118-
if (d != null) {
119-
PyObject doc = d.__finditem__("__doc__");
120-
if(doc != null) {
121-
return doc;
122-
}
123-
}
124-
return Py.None;
125-
}
126-
127114
/**
128115
* Dispatch __init__ behavior
129116
*/

src/org/python/core/PyReflectedFunction.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,6 @@ public PyObject _doget(PyObject container, PyObject wherefound) {
5353
container, wherefound);
5454
}
5555

56-
@Override
57-
public PyObject getDoc() {
58-
return __doc__;
59-
}
60-
6156
private ReflectedArgs makeArgs(Method m) {
6257
return new ReflectedArgs(m,
6358
m.getParameterTypes(),

src/org/python/core/PyType.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,8 @@ private void createAllSlots(boolean mayAddDict, boolean mayAddWeak) {
292292
* Create the __dict__ descriptor.
293293
*/
294294
private void createDictSlot() {
295-
dict.__setitem__("__dict__", new PyDataDescr(this, "__dict__", PyObject.class) {
295+
String doc = "dictionary for instance variables (if defined)";
296+
dict.__setitem__("__dict__", new PyDataDescr(this, "__dict__", PyObject.class, doc) {
296297
@Override
297298
public Object invokeGet(PyObject obj) {
298299
return obj.getDict();
@@ -325,7 +326,8 @@ public void invokeDelete(PyObject obj) {
325326
* Create the __weakref__ descriptor.
326327
*/
327328
private void createWeakrefSlot() {
328-
dict.__setitem__("__weakref__", new PyDataDescr(this, "__weakref__", PyObject.class) {
329+
String doc = "list of weak references to the object (if defined)";
330+
dict.__setitem__("__weakref__", new PyDataDescr(this, "__weakref__", PyObject.class, doc) {
329331
private static final String writeMsg =
330332
"attribute '%s' of '%s' objects is not writable";
331333

@@ -484,6 +486,21 @@ protected void init(Class<?> forClass, Set<PyJavaType> needsInners) {
484486
TypeBuilder builder = classToBuilder.get(underlying_class);
485487
name = builder.getName();
486488
dict = builder.getDict(this);
489+
String doc = builder.getDoc();
490+
// XXX: Can't create a __doc__ str until the PyBaseString/PyString types are
491+
// created
492+
if (dict.__finditem__("__doc__") == null && forClass != PyBaseString.class
493+
&& forClass != PyString.class) {
494+
PyObject docObj;
495+
if (doc != null) {
496+
docObj = new PyString(doc);
497+
} else {
498+
// XXX: Hack: Py.None may be null during bootstrapping. Most types
499+
// encountered then should have docstrings anyway
500+
docObj = Py.None == null ? new PyString() : Py.None;
501+
}
502+
dict.__setitem__("__doc__", docObj);
503+
}
487504
setIsBaseType(builder.getIsBaseType());
488505
instantiable = dict.__finditem__("__new__") != null;
489506
fillHasSetAndDelete();
@@ -1543,14 +1560,15 @@ public void delDict() {
15431560
}
15441561

15451562
/**
1546-
* Equivalent of CPython's typeobject type_get_doc; handles __doc__ descriptors.
1563+
* Equivalent of CPython's typeobject.c::type_get_doc; handles __doc__ descriptors.
15471564
*/
1565+
@ExposedGet(name = "__doc__")
15481566
public PyObject getDoc() {
1549-
PyObject doc = super.getDoc();
1550-
if (!builtin && doc != null && doc.getType().lookup("__get__") != null) {
1551-
return doc.__get__(null, this);
1567+
PyObject doc = dict.__finditem__("__doc__");
1568+
if (doc == null) {
1569+
return Py.None;
15521570
}
1553-
return doc;
1571+
return doc.__get__(null, this);
15541572
}
15551573

15561574
boolean getUsesObjectGetattribute() {

src/org/python/expose/BaseTypeBuilder.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,20 @@ public class BaseTypeBuilder implements TypeBuilder {
2424

2525
private boolean isBaseType;
2626

27+
private String doc;
28+
2729
public BaseTypeBuilder(String name,
2830
Class<?> typeClass,
2931
Class<?> baseClass,
3032
boolean isBaseType,
33+
String doc,
3134
PyBuiltinMethod[] meths,
3235
PyDataDescr[] descrs,
3336
PyNewWrapper newWrapper) {
3437
this.typeClass = typeClass;
3538
this.baseClass = baseClass;
3639
this.isBaseType = isBaseType;
40+
this.doc = doc;
3741
this.name = name;
3842
this.descrs = descrs;
3943
this.meths = meths;
@@ -72,4 +76,8 @@ public Class<?> getBase() {
7276
public boolean getIsBaseType() {
7377
return isBaseType;
7478
}
79+
80+
public String getDoc() {
81+
return doc;
82+
}
7583
}

0 commit comments

Comments
 (0)