Revision: 7237
http://jython.svn.sourceforge.net/jython/?rev=7237&view=rev
Author: pjenvey
Date: 2011-03-14 16:30:18 +0000 (Mon, 14 Mar 2011)
Log Message:
-----------
add property.getter/setter/deleter
Modified Paths:
--------------
trunk/jython/src/org/python/core/PyProperty.java
Modified: trunk/jython/src/org/python/core/PyProperty.java
===================================================================
--- trunk/jython/src/org/python/core/PyProperty.java 2011-03-14 04:31:54 UTC (rev 7236)
+++ trunk/jython/src/org/python/core/PyProperty.java 2011-03-14 16:30:18 UTC (rev 7237)
@@ -1,3 +1,4 @@
+/* Copyright (c) Jython Developers */
package org.python.core;
import org.python.expose.ExposedGet;
@@ -19,6 +20,9 @@
@ExposedGet(doc = BuiltinDocs.property_fdel_doc)
protected PyObject fdel;
+ /** Whether this property's __doc__ was copied from its getter. */
+ protected boolean docFromGetter;
+
@ExposedGet(name = "__doc__")
protected PyObject doc;
@@ -30,9 +34,8 @@
super(subType);
}
- //XXX: needs __doc__
@ExposedNew
- @ExposedMethod
+ @ExposedMethod(doc = BuiltinDocs.property___init___doc)
public void property___init__(PyObject[] args, String[] keywords) {
ArgParser ap = new ArgParser("property", args, keywords,
new String[] {"fget", "fset", "fdel", "doc"}, 0);
@@ -46,14 +49,24 @@
// if no docstring given and the getter has one, use fget's
if ((doc == null || doc == Py.None) && fget != null) {
- doc = fget.__findattr__("__doc__");
+ PyObject getDoc = fget.__findattr__("__doc__");
+ if (getType() == TYPE) {
+ doc = getDoc;
+ } else {
+ // Put __doc__ in dict of the subclass instance instead, otherwise it gets
+ // shadowed by class's __doc__
+ __setattr__("__doc__", getDoc);
+ }
+ docFromGetter = true;
}
}
+ @Override
public PyObject __call__(PyObject arg1, PyObject args[], String keywords[]) {
return fget.__call__(arg1);
}
+ @Override
public PyObject __get__(PyObject obj, PyObject type) {
return property___get__(obj,type);
}
@@ -69,6 +82,7 @@
return fget.__call__(obj);
}
+ @Override
public void __set__(PyObject obj, PyObject value) {
property___set__(obj, value);
}
@@ -81,6 +95,7 @@
fset.__call__(obj, value);
}
+ @Override
public void __delete__(PyObject obj) {
property___delete__(obj);
}
@@ -92,4 +107,57 @@
}
fdel.__call__(obj);
}
+
+ public PyObject getter(PyObject getter) {
+ return property_getter(getter);
+ }
+
+ @ExposedMethod(doc = BuiltinDocs.property_getter_doc)
+ final PyObject property_getter(PyObject getter) {
+ return propertyCopy(getter, null, null);
+ }
+
+ public PyObject setter(PyObject setter) {
+ return property_setter(setter);
+ }
+
+ @ExposedMethod(doc = BuiltinDocs.property_setter_doc)
+ final PyObject property_setter(PyObject setter) {
+ return propertyCopy(null, setter, null);
+ }
+
+ public PyObject deleter(PyObject deleter) {
+ return property_deleter(deleter);
+ }
+
+ @ExposedMethod(doc = BuiltinDocs.property_deleter_doc)
+ final PyObject property_deleter(PyObject deleter) {
+ return propertyCopy(null, null, deleter);
+ }
+
+ /**
+ * Return a copy of this property with the optional addition of a get/set/del. Helper
+ * method for the getter/setter/deleter methods.
+ */
+ private PyObject propertyCopy(PyObject get, PyObject set, PyObject del) {
+ if (get == null) {
+ get = fget != null ? fget : Py.None;
+ }
+ if (set == null) {
+ set = fset != null ? fset : Py.None;
+ }
+ if (del == null) {
+ del = fdel != null ? fdel : Py.None;
+ }
+
+ PyObject doc;
+ if (docFromGetter) {
+ // make _init use __doc__ from getter
+ doc = Py.None;
+ } else {
+ doc = this.doc != null ? this.doc : Py.None;
+ }
+
+ return getType().__call__(get, set, del, doc);
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|