Index: src/templates/str.expose =================================================================== --- src/templates/str.expose (revision 3470) +++ src/templates/str.expose (working copy) @@ -52,5 +52,7 @@ expose_meth: :s title expose_meth: :s translate s s? expose_meth: :s upper expose_meth: :s zfill i +expose_meth: partition s +expose_meth: rpartition s expose_new_immutable: #expose_meth: :b __nonzero__ Index: src/templates/unicode.expose =================================================================== --- src/templates/unicode.expose (revision 3470) +++ src/templates/unicode.expose (working copy) @@ -51,6 +51,8 @@ expose_meth: :u title expose_meth: :u translate o expose_meth: :u upper expose_meth: :u zfill i +expose_meth: partition s +expose_meth: rpartition s expose_new_immutable: #TODO #expose_meth: :b __nonzero__ Index: src/org/python/core/PyString.java =================================================================== --- src/org/python/core/PyString.java (revision 3470) +++ src/org/python/core/PyString.java (working copy) @@ -1549,6 +1549,62 @@ public class PyString extends PyBaseStri } dict.__setitem__("zfill",new PyMethodDescr("zfill",PyString.class,1,1,new exposed_zfill(null,null))); + class exposed_partition extends PyBuiltinMethodNarrow { + + exposed_partition(PyObject self,PyBuiltinFunction.Info info) { + super(self,info); + } + + public PyBuiltinFunction bind(PyObject self) { + return new exposed_partition(self,info); + } + + public PyObject __call__(PyObject arg0) { + try { + return((PyString)self).str_partition(arg0.asString(0)); + } catch (PyObject.ConversionException e) { + String msg; + switch (e.index) { + case 0: + msg="expected a string"; + break; + default: + msg="xxx"; + } + throw Py.TypeError(msg); + } + } + + } + dict.__setitem__("partition",new PyMethodDescr("partition",PyString.class,1,1,new exposed_partition(null,null))); + class exposed_rpartition extends PyBuiltinMethodNarrow { + + exposed_rpartition(PyObject self,PyBuiltinFunction.Info info) { + super(self,info); + } + + public PyBuiltinFunction bind(PyObject self) { + return new exposed_rpartition(self,info); + } + + public PyObject __call__(PyObject arg0) { + try { + return((PyString)self).str_rpartition(arg0.asString(0)); + } catch (PyObject.ConversionException e) { + String msg; + switch (e.index) { + case 0: + msg="expected a string"; + break; + default: + msg="xxx"; + } + throw Py.TypeError(msg); + } + } + + } + dict.__setitem__("rpartition",new PyMethodDescr("rpartition",PyString.class,1,1,new exposed_rpartition(null,null))); dict.__setitem__("__new__",new PyNewWrapper(PyString.class,"__new__",-1,-1) { public PyObject new_impl(boolean init,PyType subtype,PyObject[]args,String[]keywords) { @@ -2604,6 +2660,43 @@ public class PyString extends PyBaseStri return list; } + + private PyTuple str_partition(String sep) { + if (sep.length() == 0) + throw Py.ValueError("empty separator"); + + int index = string.indexOf(sep); + + if (index != -1) + return new PyTuple(new PyObject[] { + fromSubstring(0, index), + Py.newString(sep),fromSubstring(index + sep.length(), string.length()) + }); + else + return new PyTuple(new PyObject[] { + Py.newString(string), + Py.newString(""), Py.newString("") + }); + } + + private PyTuple str_rpartition(String sep) { + if (sep.length() == 0) + throw Py.ValueError("empty separator"); + + int index = string.lastIndexOf(sep); + + if (index != -1) + return new PyTuple(new PyObject[] { + fromSubstring(0, index), + Py.newString(sep), fromSubstring(index + sep.length(), string.length()) + }); + else + return new PyTuple(new PyObject[] { + Py.newString(""), Py.newString(""), + Py.newString(string) + }); + } + private PyList splitfields(String sep, int maxsplit) { if (sep.length() == 0) { throw Py.ValueError("empty separator"); Index: src/org/python/core/PyUnicode.java =================================================================== --- src/org/python/core/PyUnicode.java (revision 3470) +++ src/org/python/core/PyUnicode.java (working copy) @@ -1428,6 +1428,62 @@ public class PyUnicode extends PyString } dict.__setitem__("zfill",new PyMethodDescr("zfill",PyUnicode.class,1,1,new exposed_zfill(null,null))); + class exposed_partition extends PyBuiltinMethodNarrow { + + exposed_partition(PyObject self,PyBuiltinFunction.Info info) { + super(self,info); + } + + public PyBuiltinFunction bind(PyObject self) { + return new exposed_partition(self,info); + } + + public PyObject __call__(PyObject arg0) { + try { + return((PyUnicode)self).unicode_partition(arg0.asString(0)); + } catch (PyObject.ConversionException e) { + String msg; + switch (e.index) { + case 0: + msg="expected a string"; + break; + default: + msg="xxx"; + } + throw Py.TypeError(msg); + } + } + + } + dict.__setitem__("partition",new PyMethodDescr("partition",PyUnicode.class,1,1,new exposed_partition(null,null))); + class exposed_rpartition extends PyBuiltinMethodNarrow { + + exposed_rpartition(PyObject self,PyBuiltinFunction.Info info) { + super(self,info); + } + + public PyBuiltinFunction bind(PyObject self) { + return new exposed_rpartition(self,info); + } + + public PyObject __call__(PyObject arg0) { + try { + return((PyUnicode)self).unicode_rpartition(arg0.asString(0)); + } catch (PyObject.ConversionException e) { + String msg; + switch (e.index) { + case 0: + msg="expected a string"; + break; + default: + msg="xxx"; + } + throw Py.TypeError(msg); + } + } + + } + dict.__setitem__("rpartition",new PyMethodDescr("rpartition",PyUnicode.class,1,1,new exposed_rpartition(null,null))); dict.__setitem__("__new__",new PyNewWrapper(PyUnicode.class,"__new__",-1,-1) { public PyObject new_impl(boolean init,PyType subtype,PyObject[]args,String[]keywords) { @@ -1720,6 +1776,40 @@ public class PyUnicode extends PyString return str_zfill(width); } + final PyTuple unicode_partition(String sep) { + if (sep.length() == 0) + throw Py.ValueError("empty separator"); + + int index = string.indexOf(sep); + + if (index != -1) + return new PyTuple(new PyObject[] { + fromSubstring(0, index), + Py.newUnicode(sep),fromSubstring(index + sep.length(), string.length()) + }); + else + return new PyTuple(new PyObject[] { + Py.newUnicode(string), + Py.newUnicode(""), Py.newUnicode("") + }); + } + final PyTuple unicode_rpartition(String sep) { + if (sep.length() == 0) + throw Py.ValueError("empty separator"); + + int index = string.lastIndexOf(sep); + + if (index != -1) + return new PyTuple(new PyObject[] { + fromSubstring(0, index), + Py.newUnicode(sep), fromSubstring(index + sep.length(), string.length()) + }); + else + return new PyTuple(new PyObject[] { + Py.newUnicode(""), Py.newUnicode(""), + Py.newUnicode(string) + }); } + final String unicode_expandtabs() { return str_expandtabs(); } Index: Lib/test/test_str.py =================================================================== --- Lib/test/test_str.py (revision 3470) +++ Lib/test/test_str.py (working copy) @@ -16,6 +16,14 @@ class StrTest( def test_formatting(self): string_tests.MixinStrUnicodeUserStringTest.test_formatting(self) + + def test_partition(self): + string_tests.MixinStrUnicodeUserStringTest.test_partition(self) + + def test_rpartition(self): + string_tests.MixinStrUnicodeUserStringTest.test_rpartition(self) + + # Jython transition 2.3 # values outside of the size of a single char aren't prohibited in formatting %c # http://jython.org/bugs/1768075 Index: Lib/test/string_tests.py =================================================================== --- Lib/test/string_tests.py (revision 3470) +++ Lib/test/string_tests.py (working copy) @@ -595,6 +595,35 @@ class MixinStrUnicodeUserStringTest: else: self.checkcall(format, "__mod__", value) + def test_partition(self): + self.checkequal(('this is the par', 'ti', 'tion method'), + 'this is the partition method', 'partition', 'ti') + + # from raymond's original specification + S = 'http://www.python.org' + self.checkequal(('http', '://', 'www.python.org'), S, 'partition', '://') + self.checkequal(('http://www.python.org', '', ''), S, 'partition', '?') + self.checkequal(('', 'http://', 'www.python.org'), S, 'partition', 'http://') + self.checkequal(('http://www.python.', 'org', ''), S, 'partition', 'org') + + self.checkraises(ValueError, S, 'partition', '') + self.checkraises(TypeError, S, 'partition', None) + + def test_rpartition(self): + self.checkequal(('this is the rparti', 'ti', 'on method'), + 'this is the rpartition method', 'rpartition', 'ti') + + # from raymond's original specification + S = 'http://www.python.org' + self.checkequal(('http', '://', 'www.python.org'), S, 'rpartition', '://') + self.checkequal(('', '', 'http://www.python.org'), S, 'rpartition', '?') + self.checkequal(('', 'http://', 'www.python.org'), S, 'rpartition', 'http://') + self.checkequal(('http://www.python.', 'org', ''), S, 'rpartition', 'org') + + self.checkraises(ValueError, S, 'rpartition', '') + self.checkraises(TypeError, S, 'rpartition', None) + + class MixinStrStringUserStringTest: # Additional tests for 8bit strings, i.e. str, UserString and # the string module