From: <nr...@us...> - 2008-08-16 06:09:36
|
Revision: 5185 http://jython.svn.sourceforge.net/jython/?rev=5185&view=rev Author: nriley Date: 2008-08-16 06:09:33 +0000 (Sat, 16 Aug 2008) Log Message: ----------- Permit removal/modification of attributes on PySystemState; add __name__. Modified Paths: -------------- branches/asm/Lib/test/test_sys_jy.py branches/asm/src/org/python/core/PySystemState.java branches/asm/src/org/python/core/__builtin__.java Modified: branches/asm/Lib/test/test_sys_jy.py =================================================================== --- branches/asm/Lib/test/test_sys_jy.py 2008-08-16 05:35:48 UTC (rev 5184) +++ branches/asm/Lib/test/test_sys_jy.py 2008-08-16 06:09:33 UTC (rev 5185) @@ -4,11 +4,11 @@ import test.test_support class SysTest(unittest.TestCase): - + def test_platform(self): self.assertEquals(sys.platform[:4], "java", "sys.platform is not java") - + def test_exit_arg(self): "sys.exit can be called with args" try: @@ -25,8 +25,43 @@ tb = sys.exc_info()[2] if tb.tb_lineno == 0: self.fail("Traceback lineno was zero") - + def test_name(self): + "sys.__name__ can be reassigned/deleted" + self.assertEquals(sys.__name__, 'sys') + sys.__name__ = 'foo' + self.assert_('foo' in str(sys)) + del sys.__name__ + self.assert_('foo' not in str(sys)) + sys.__name__ = 'sys' + + def test_readonly(self): + def deleteClass(): del sys.__class__ + self.assertRaises(TypeError, deleteClass) + + def deleteDict(): del sys.__dict__ + self.assertRaises(TypeError, deleteDict) + + def assignClass(): sys.__class__ = object + self.assertRaises(TypeError, assignClass) + + def assignDict(): sys.__dict__ = {} + self.assertRaises(TypeError, assignDict) + + def test_resetmethod(self): + gde = sys.getdefaultencoding + sys.getdefaultencoding = 5 + self.assertEquals(sys.getdefaultencoding, 5) + del sys.getdefaultencoding + self.assertRaises(AttributeError, getattr, sys, 'getdefaultencoding') + sys.getdefaultencoding = gde + + def test_reload(self): + gde = sys.getdefaultencoding + del sys.getdefaultencoding + reload(sys) + self.assert_(type(sys.getdefaultencoding) == type(gde)) + def test_main(): test.test_support.run_unittest(SysTest) Modified: branches/asm/src/org/python/core/PySystemState.java =================================================================== --- branches/asm/src/org/python/core/PySystemState.java 2008-08-16 05:35:48 UTC (rev 5184) +++ branches/asm/src/org/python/core/PySystemState.java 2008-08-16 06:09:33 UTC (rev 5185) @@ -129,6 +129,8 @@ public PyObject last_type = Py.None; public PyObject last_traceback = Py.None; + public PyObject __name__ = new PyString("sys"); + public PyObject __dict__; private int recursionlimit = 1000; @@ -168,13 +170,22 @@ PyModule __builtin__ = new PyModule("__builtin__", builtins); modules.__setitem__("__builtin__", __builtin__); - if (getType() != null) { - __dict__ = new PyStringMap(); - __dict__.invoke("update", getType().fastGetDict()); - __dict__.__setitem__("displayhook", __displayhook__); - __dict__.__setitem__("excepthook", __excepthook__); - } + __dict__ = new PyStringMap(); + + // This isn't right either, because __dict__ can be directly + // accessed from Python, for example: + // + // >>> sys.__dict__['settrace'] + // <java function settrace 81> + + __dict__.invoke("update", getType().fastGetDict()); + __dict__.__setitem__("displayhook", __displayhook__); + __dict__.__setitem__("excepthook", __excepthook__); } + + void reload() throws PyIgnoreMethodTag { + __dict__.invoke("update", getType().fastGetDict()); + } // xxx fix this accessors public PyObject __findattr_ex__(String name) { @@ -200,33 +211,43 @@ } PyObject ret = super.__findattr_ex__(name); - if (ret != null) return ret; + if (ret != null) { + if (ret instanceof PyMethod) { + if (__dict__.__finditem__(name) instanceof PyReflectedFunction) + return ret; // xxx hack + } else if (ret == PyAttributeDeleted.INSTANCE) { + return null; + } + else return ret; + } return __dict__.__finditem__(name); } public void __setattr__(String name, PyObject value) { - PyType selftype = getType(); - if (selftype == null) + if (name == "__dict__" || name == "__class__") + throw Py.TypeError("readonly attribute"); + PyObject ret = getType().lookup(name); // xxx fix fix fix + if (ret != null && ret.jtryset(this, value)) { return; - PyObject ret = selftype.lookup(name); // xxx fix fix fix - if (ret != null) { - ret.jtryset(this, value); - return; } - if (__dict__ == null) { - __dict__ = new PyStringMap(); - } __dict__.__setitem__(name, value); - //throw Py.AttributeError(name); } public void __delattr__(String name) { - if (__dict__ != null) { + if (name == "__dict__" || name == "__class__") + throw Py.TypeError("readonly attribute"); + PyObject ret = getType().lookup(name); // xxx fix fix fix + if (ret != null) { + ret.jtryset(this, PyAttributeDeleted.INSTANCE); + } + try { __dict__.__delitem__(name); - return; + } catch (PyException pye) { // KeyError + if (ret == null) { + throw Py.AttributeError(name); + } } - throw Py.AttributeError("del '"+name+"'"); } // xxx @@ -235,7 +256,7 @@ } public String toString() { - return "sys module"; + return "<module '" + __name__ + "' (built-in)>"; } public int getrecursionlimit() { @@ -945,3 +966,22 @@ } } } + +/** + * Value of a class or instance variable when the corresponding + * attribute is deleted. Used only in PySystemState for now. + */ +class PyAttributeDeleted extends PyObject { + final static PyAttributeDeleted INSTANCE = new PyAttributeDeleted(); + private PyAttributeDeleted() {} + public String toString() { return ""; } + public Object __tojava__(Class c) { + if (c == PyObject.class) + return this; + // we can't quite "delete" non-PyObject attributes; settle for + // null or nothing + if (c.isPrimitive()) + return Py.NoConversion; + return null; + } +} Modified: branches/asm/src/org/python/core/__builtin__.java =================================================================== --- branches/asm/src/org/python/core/__builtin__.java 2008-08-16 05:35:48 UTC (rev 5184) +++ branches/asm/src/org/python/core/__builtin__.java 2008-08-16 06:09:33 UTC (rev 5185) @@ -1075,7 +1075,8 @@ } public static PyObject reload(PySystemState o) { - // fake it like imp.reload(PyJavaClass) does + // reinitialize methods + o.reload(); return o; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |