[Jython-checkins] jython: Basic implementation of buffer type.

jeff.allen jython-checkins at python.org
Fri Sep 27 21:17:19 CEST 2013


http://hg.python.org/jython/rev/2751805d22a5
changeset:   7129:2751805d22a5
user:        Jeff Allen <ja.py at farowl.co.uk>
date:        Fri Sep 27 09:11:34 2013 +0100
summary:
  Basic implementation of buffer type.
Reasonably complete buffer implementation Py2kBuffer with slicing.
Enable regression test for that. (Bug revealed & fixed in buffers on strings.)
Many gaps exist in acceptability of buffer as an argument in library types.

files:
  CoreExposed.includes                               |    1 +
  Lib/test/regrtest.py                               |    1 -
  Lib/test/test_unicode.py                           |   13 +-
  Misc/make_pydocs.py                                |    2 +-
  src/org/python/core/BuiltinDocs.java               |  712 +++++----
  src/org/python/core/Py2kBuffer.java                |  619 ++++++++
  src/org/python/core/PyUnicode.java                 |   25 +-
  src/org/python/core/__builtin__.java               |    1 +
  src/org/python/core/buffer/SimpleStringBuffer.java |   10 +-
  9 files changed, 1057 insertions(+), 327 deletions(-)


diff --git a/CoreExposed.includes b/CoreExposed.includes
--- a/CoreExposed.includes
+++ b/CoreExposed.includes
@@ -1,5 +1,6 @@
 org/python/core/AstList.class
 org/python/core/ClasspathPyImporter.class
+org/python/core/Py2kBuffer.class
 org/python/core/PyArray.class
 org/python/core/PyBaseString.class
 org/python/core/PyBaseException.class
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -1187,7 +1187,6 @@
         test_applesingle
         test_ascii_formatd
         test_audioop
-        test_buffer
         test_bsddb
         test_bsddb185
         test_bsddb3
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -452,15 +452,10 @@
             u'strings are decoded to unicode'
         )
 
-        if not sys.platform.startswith('java'):
-            self.assertEqual(
-                unicode(
-                    buffer('character buffers are decoded to unicode'),
-                    'utf-8',
-                    'strict'
-                ),
-                u'character buffers are decoded to unicode'
-            )
+        self.assertEqual(
+            unicode('strings are decoded to unicode', 'utf-8', 'strict'),
+            u'strings are decoded to unicode'
+        )
 
         self.assertRaises(TypeError, unicode, 42, 42, 42)
 
diff --git a/Misc/make_pydocs.py b/Misc/make_pydocs.py
--- a/Misc/make_pydocs.py
+++ b/Misc/make_pydocs.py
@@ -61,7 +61,7 @@
 frozenset,
 BaseException,
 bytearray,
-#buffer,
+buffer,
 memoryview,
 # +
 type(f),
diff --git a/src/org/python/core/BuiltinDocs.java b/src/org/python/core/BuiltinDocs.java
--- a/src/org/python/core/BuiltinDocs.java
+++ b/src/org/python/core/BuiltinDocs.java
@@ -2196,9 +2196,7 @@
         "Return a copy of the string S, where all characters occurring\n" + 
         "in the optional argument deletechars are removed, and the\n" + 
         "remaining characters have been mapped through the given\n" + 
-        "translation table, which must be a string of length 256.\n" +
-        "If the table argument is None, no translation is applied and\n" +
-        "the operation simply removes the characters in deletechars.";
+        "translation table, which must be a string of length 256.";
 
     public final static String str_upper_doc = 
         "S.upper() -> string\n" + 
@@ -4049,84 +4047,96 @@
         "Pad a numeric string B with zeros on the left, to fill a field\n" + 
         "of the specified width.  B is never truncated.";
 
-    // Docs for <type 'memoryview'>
-    public final static String memoryview___class___doc = 
+    // Docs for <type 'buffer'>
+    public final static String buffer___add___doc = 
+        "x.__add__(y) <==> x+y";
+
+    public final static String buffer___class___doc = 
         "type(object) -> the object's type\n" + 
         "type(name, bases, dict) -> a new type";
 
-    public final static String memoryview___delattr___doc = 
+    public final static String buffer___cmp___doc = 
+        "x.__cmp__(y) <==> cmp(x,y)";
+
+    public final static String buffer___delattr___doc = 
         "x.__delattr__('name') <==> del x.name";
 
-    public final static String memoryview___delitem___doc = 
+    public final static String buffer___delitem___doc = 
         "x.__delitem__(y) <==> del x[y]";
 
-    public final static String memoryview_doc = 
-        "memoryview(object)\n" + 
-        "\n" + 
-        "Create a new memoryview object which references the given object.";
-
-    public final static String memoryview___eq___doc = 
-        "x.__eq__(y) <==> x==y";
-
-    public final static String memoryview___format___doc = 
+    public final static String buffer___delslice___doc = 
+        "x.__delslice__(i, j) <==> del x[i:j]\n" + 
+        "           \n" + 
+        "           Use of negative indices is not supported.";
+
+    public final static String buffer_doc = 
+        "buffer(object [, offset[, size]])\n" + 
+        "\n" + 
+        "Create a new buffer object which references the given object.\n" + 
+        "The buffer will reference a slice of the target object from the\n" + 
+        "start of the object (or at the specified offset). The slice will\n" + 
+        "extend to the end of the target object (or with the specified size).";
+
+    public final static String buffer___format___doc = 
         "default object formatter";
 
-    public final static String memoryview___ge___doc = 
-        "x.__ge__(y) <==> x>=y";
-
-    public final static String memoryview___getattribute___doc = 
+    public final static String buffer___getattribute___doc = 
         "x.__getattribute__('name') <==> x.name";
 
-    public final static String memoryview___getitem___doc = 
+    public final static String buffer___getitem___doc = 
         "x.__getitem__(y) <==> x[y]";
 
-    public final static String memoryview___gt___doc = 
-        "x.__gt__(y) <==> x>y";
-
-    public final static String memoryview___hash___doc = 
+    public final static String buffer___getslice___doc = 
+        "x.__getslice__(i, j) <==> x[i:j]\n" + 
+        "           \n" + 
+        "           Use of negative indices is not supported.";
+
+    public final static String buffer___hash___doc = 
         "x.__hash__() <==> hash(x)";
 
-    public final static String memoryview___init___doc = 
+    public final static String buffer___init___doc = 
         "x.__init__(...) initializes x; see help(type(x)) for signature";
 
-    public final static String memoryview___le___doc = 
-        "x.__le__(y) <==> x<=y";
-
-    public final static String memoryview___len___doc = 
+    public final static String buffer___len___doc = 
         "x.__len__() <==> len(x)";
 
-    public final static String memoryview___lt___doc = 
-        "x.__lt__(y) <==> x<y";
-
-    public final static String memoryview___ne___doc = 
-        "x.__ne__(y) <==> x!=y";
-
-    public final static String memoryview___new___doc = 
+    public final static String buffer___mul___doc = 
+        "x.__mul__(n) <==> x*n";
+
+    public final static String buffer___new___doc = 
         "T.__new__(S, ...) -> a new object with type S, a subtype of T";
 
-    public final static String memoryview___reduce___doc = 
+    public final static String buffer___reduce___doc = 
         "helper for pickle";
 
-    public final static String memoryview___reduce_ex___doc = 
+    public final static String buffer___reduce_ex___doc = 
         "helper for pickle";
 
-    public final static String memoryview___repr___doc = 
+    public final static String buffer___repr___doc = 
         "x.__repr__() <==> repr(x)";
 
-    public final static String memoryview___setattr___doc = 
+    public final static String buffer___rmul___doc = 
+        "x.__rmul__(n) <==> n*x";
+
+    public final static String buffer___setattr___doc = 
         "x.__setattr__('name', value) <==> x.name = value";
 
-    public final static String memoryview___setitem___doc = 
+    public final static String buffer___setitem___doc = 
         "x.__setitem__(i, y) <==> x[i]=y";
 
-    public final static String memoryview___sizeof___doc = 
+    public final static String buffer___setslice___doc = 
+        "x.__setslice__(i, j, y) <==> x[i:j]=y\n" + 
+        "           \n" + 
+        "           Use  of negative indices is not supported.";
+
+    public final static String buffer___sizeof___doc = 
         "__sizeof__() -> int\n" + 
         "size of object in memory, in bytes";
 
-    public final static String memoryview___str___doc = 
+    public final static String buffer___str___doc = 
         "x.__str__() <==> str(x)";
 
-    public final static String memoryview___subclasshook___doc = 
+    public final static String buffer___subclasshook___doc = 
         "Abstract classes can override this to customize issubclass().\n" + 
         "\n" + 
         "This is invoked early on by abc.ABCMeta.__subclasscheck__().\n" + 
@@ -4135,117 +4145,84 @@
         "overrides the normal algorithm (and the outcome is cached).\n" + 
         "";
 
-    public final static String memoryview_format_doc = 
-        "";
-
-    public final static String memoryview_itemsize_doc = 
-        "";
-
-    public final static String memoryview_ndim_doc = 
-        "";
-
-    public final static String memoryview_readonly_doc = 
-        "";
-
-    public final static String memoryview_shape_doc = 
-        "";
-
-    public final static String memoryview_strides_doc = 
-        "";
-
-    public final static String memoryview_suboffsets_doc = 
-        "";
-
-    public final static String memoryview_tobytes_doc = 
-        "";
-
-    public final static String memoryview_tolist_doc = 
-        "";
-
-    // Docs for <type 'function'>
-    public final static String function___call___doc = 
-        "x.__call__(...) <==> x(...)";
-
-    public final static String function___class___doc = 
+    // Docs for <type 'memoryview'>
+    public final static String memoryview___class___doc = 
         "type(object) -> the object's type\n" + 
         "type(name, bases, dict) -> a new type";
 
-    public final static String function___closure___doc = 
-        "";
-
-    public final static String function___code___doc = 
-        "";
-
-    public final static String function___defaults___doc = 
-        "";
-
-    public final static String function___delattr___doc = 
+    public final static String memoryview___delattr___doc = 
         "x.__delattr__('name') <==> del x.name";
 
-    public final static String function___dict___doc = 
-        "";
-
-    public final static String function_doc = 
-        "function(code, globals[, name[, argdefs[, closure]]])\n" + 
-        "\n" + 
-        "Create a function object from a code object and a dictionary.\n" + 
-        "The optional name string overrides the name from the code object.\n" + 
-        "The optional argdefs tuple specifies the default argument values.\n" + 
-        "The optional closure tuple supplies the bindings for free variables.";
-
-    public final static String function___format___doc = 
+    public final static String memoryview___delitem___doc = 
+        "x.__delitem__(y) <==> del x[y]";
+
+    public final static String memoryview_doc = 
+        "memoryview(object)\n" + 
+        "\n" + 
+        "Create a new memoryview object which references the given object.";
+
+    public final static String memoryview___eq___doc = 
+        "x.__eq__(y) <==> x==y";
+
+    public final static String memoryview___format___doc = 
         "default object formatter";
 
-    public final static String function___get___doc = 
-        "descr.__get__(obj[, type]) -> value";
-
-    public final static String function___getattribute___doc = 
+    public final static String memoryview___ge___doc = 
+        "x.__ge__(y) <==> x>=y";
+
+    public final static String memoryview___getattribute___doc = 
         "x.__getattribute__('name') <==> x.name";
 
-    public final static String function___globals___doc = 
-        "";
-
-    public final static String function___hash___doc = 
+    public final static String memoryview___getitem___doc = 
+        "x.__getitem__(y) <==> x[y]";
+
+    public final static String memoryview___gt___doc = 
+        "x.__gt__(y) <==> x>y";
+
+    public final static String memoryview___hash___doc = 
         "x.__hash__() <==> hash(x)";
 
-    public final static String function___init___doc = 
+    public final static String memoryview___init___doc = 
         "x.__init__(...) initializes x; see help(type(x)) for signature";
 
-    public final static String function___module___doc = 
-        "str(object) -> string\n" + 
-        "\n" + 
-        "Return a nice string representation of the object.\n" + 
-        "If the argument is a string, the return value is the same object.";
-
-    public final static String function___name___doc = 
-        "str(object) -> string\n" + 
-        "\n" + 
-        "Return a nice string representation of the object.\n" + 
-        "If the argument is a string, the return value is the same object.";
-
-    public final static String function___new___doc = 
+    public final static String memoryview___le___doc = 
+        "x.__le__(y) <==> x<=y";
+
+    public final static String memoryview___len___doc = 
+        "x.__len__() <==> len(x)";
+
+    public final static String memoryview___lt___doc = 
+        "x.__lt__(y) <==> x<y";
+
+    public final static String memoryview___ne___doc = 
+        "x.__ne__(y) <==> x!=y";
+
+    public final static String memoryview___new___doc = 
         "T.__new__(S, ...) -> a new object with type S, a subtype of T";
 
-    public final static String function___reduce___doc = 
+    public final static String memoryview___reduce___doc = 
         "helper for pickle";
 
-    public final static String function___reduce_ex___doc = 
+    public final static String memoryview___reduce_ex___doc = 
         "helper for pickle";
 
-    public final static String function___repr___doc = 
+    public final static String memoryview___repr___doc = 
         "x.__repr__() <==> repr(x)";
 
-    public final static String function___setattr___doc = 
+    public final static String memoryview___setattr___doc = 
         "x.__setattr__('name', value) <==> x.name = value";
 
-    public final static String function___sizeof___doc = 
+    public final static String memoryview___setitem___doc = 
+        "x.__setitem__(i, y) <==> x[i]=y";
+
+    public final static String memoryview___sizeof___doc = 
         "__sizeof__() -> int\n" + 
         "size of object in memory, in bytes";
 
-    public final static String function___str___doc = 
+    public final static String memoryview___str___doc = 
         "x.__str__() <==> str(x)";
 
-    public final static String function___subclasshook___doc = 
+    public final static String memoryview___subclasshook___doc = 
         "Abstract classes can override this to customize issubclass().\n" + 
         "\n" + 
         "This is invoked early on by abc.ABCMeta.__subclasscheck__().\n" + 
@@ -4254,90 +4231,117 @@
         "overrides the normal algorithm (and the outcome is cached).\n" + 
         "";
 
-    public final static String function_func_closure_doc = 
+    public final static String memoryview_format_doc = 
         "";
 
-    public final static String function_func_code_doc = 
+    public final static String memoryview_itemsize_doc = 
         "";
 
-    public final static String function_func_defaults_doc = 
+    public final static String memoryview_ndim_doc = 
         "";
 
-    public final static String function_func_dict_doc = 
+    public final static String memoryview_readonly_doc = 
         "";
 
-    public final static String function_func_doc_doc = 
+    public final static String memoryview_shape_doc = 
         "";
 
-    public final static String function_func_globals_doc = 
+    public final static String memoryview_strides_doc = 
         "";
 
-    public final static String function_func_name_doc = 
+    public final static String memoryview_suboffsets_doc = 
         "";
 
-    // Docs for <type 'instancemethod'>
-    public final static String instancemethod___call___doc = 
+    public final static String memoryview_tobytes_doc = 
+        "";
+
+    public final static String memoryview_tolist_doc = 
+        "";
+
+    // Docs for <type 'function'>
+    public final static String function___call___doc = 
         "x.__call__(...) <==> x(...)";
 
-    public final static String instancemethod___class___doc = 
+    public final static String function___class___doc = 
         "type(object) -> the object's type\n" + 
         "type(name, bases, dict) -> a new type";
 
-    public final static String instancemethod___cmp___doc = 
-        "x.__cmp__(y) <==> cmp(x,y)";
-
-    public final static String instancemethod___delattr___doc = 
+    public final static String function___closure___doc = 
+        "";
+
+    public final static String function___code___doc = 
+        "";
+
+    public final static String function___defaults___doc = 
+        "";
+
+    public final static String function___delattr___doc = 
         "x.__delattr__('name') <==> del x.name";
 
-    public final static String instancemethod_doc = 
-        "instancemethod(function, instance, class)\n" + 
-        "\n" + 
-        "Create an instance method object.";
-
-    public final static String instancemethod___format___doc = 
+    public final static String function___dict___doc = 
+        "";
+
+    public final static String function_doc = 
+        "function(code, globals[, name[, argdefs[, closure]]])\n" + 
+        "\n" + 
+        "Create a function object from a code object and a dictionary.\n" + 
+        "The optional name string overrides the name from the code object.\n" + 
+        "The optional argdefs tuple specifies the default argument values.\n" + 
+        "The optional closure tuple supplies the bindings for free variables.";
+
+    public final static String function___format___doc = 
         "default object formatter";
 
-    public final static String instancemethod___func___doc = 
-        "the function (or other callable) implementing a method";
-
-    public final static String instancemethod___get___doc = 
+    public final static String function___get___doc = 
         "descr.__get__(obj[, type]) -> value";
 
-    public final static String instancemethod___getattribute___doc = 
+    public final static String function___getattribute___doc = 
         "x.__getattribute__('name') <==> x.name";
 
-    public final static String instancemethod___hash___doc = 
+    public final static String function___globals___doc = 
+        "";
+
+    public final static String function___hash___doc = 
         "x.__hash__() <==> hash(x)";
 
-    public final static String instancemethod___init___doc = 
+    public final static String function___init___doc = 
         "x.__init__(...) initializes x; see help(type(x)) for signature";
 
-    public final static String instancemethod___new___doc = 
+    public final static String function___module___doc = 
+        "str(object) -> string\n" + 
+        "\n" + 
+        "Return a nice string representation of the object.\n" + 
+        "If the argument is a string, the return value is the same object.";
+
+    public final static String function___name___doc = 
+        "str(object) -> string\n" + 
+        "\n" + 
+        "Return a nice string representation of the object.\n" + 
+        "If the argument is a string, the return value is the same object.";
+
+    public final static String function___new___doc = 
         "T.__new__(S, ...) -> a new object with type S, a subtype of T";
 
-    public final static String instancemethod___reduce___doc = 
+    public final static String function___reduce___doc = 
         "helper for pickle";
 
-    public final static String instancemethod___reduce_ex___doc = 
+    public final static String function___reduce_ex___doc = 
         "helper for pickle";
 
-    public final static String instancemethod___repr___doc = 
+    public final static String function___repr___doc = 
         "x.__repr__() <==> repr(x)";
 
-    public final static String instancemethod___self___doc = 
-        "the instance to which a method is bound; None for unbound methods";
-
-    public final static String instancemethod___setattr___doc = 
+    public final static String function___setattr___doc = 
         "x.__setattr__('name', value) <==> x.name = value";
 
-    public final static String instancemethod___sizeof___doc = 
+    public final static String function___sizeof___doc = 
         "__sizeof__() -> int\n" + 
         "size of object in memory, in bytes";
 
-    public final static String instancemethod___str___doc = 
+    public final static String function___str___doc = 
         "x.__str__() <==> str(x)";
 
-    public final static String instancemethod___subclasshook___doc = 
+    public final static String function___subclasshook___doc = 
         "Abstract classes can override this to customize issubclass().\n" + 
         "\n" + 
         "This is invoked early on by abc.ABCMeta.__subclasscheck__().\n" + 
@@ -4346,85 +4350,90 @@
         "overrides the normal algorithm (and the outcome is cached).\n" + 
         "";
 
-    public final static String instancemethod_im_class_doc = 
-        "the class associated with a method";
-
-    public final static String instancemethod_im_func_doc = 
-        "the function (or other callable) implementing a method";
-
-    public final static String instancemethod_im_self_doc = 
-        "the instance to which a method is bound; None for unbound methods";
-
-    // Docs for <type 'code'>
-    public final static String code___class___doc = 
+    public final static String function_func_closure_doc = 
+        "";
+
+    public final static String function_func_code_doc = 
+        "";
+
+    public final static String function_func_defaults_doc = 
+        "";
+
+    public final static String function_func_dict_doc = 
+        "";
+
+    public final static String function_func_doc_doc = 
+        "";
+
+    public final static String function_func_globals_doc = 
+        "";
+
+    public final static String function_func_name_doc = 
+        "";
+
+    // Docs for <type 'instancemethod'>
+    public final static String instancemethod___call___doc = 
+        "x.__call__(...) <==> x(...)";
+
+    public final static String instancemethod___class___doc = 
         "type(object) -> the object's type\n" + 
         "type(name, bases, dict) -> a new type";
 
-    public final static String code___cmp___doc = 
+    public final static String instancemethod___cmp___doc = 
         "x.__cmp__(y) <==> cmp(x,y)";
 
-    public final static String code___delattr___doc = 
+    public final static String instancemethod___delattr___doc = 
         "x.__delattr__('name') <==> del x.name";
 
-    public final static String code_doc = 
-        "code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n" + 
-        "      varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n" + 
-        "\n" + 
-        "Create a code object.  Not for the faint of heart.";
-
-    public final static String code___eq___doc = 
-        "x.__eq__(y) <==> x==y";
-
-    public final static String code___format___doc = 
+    public final static String instancemethod_doc = 
+        "instancemethod(function, instance, class)\n" + 
+        "\n" + 
+        "Create an instance method object.";
+
+    public final static String instancemethod___format___doc = 
         "default object formatter";
 
-    public final static String code___ge___doc = 
-        "x.__ge__(y) <==> x>=y";
-
-    public final static String code___getattribute___doc = 
+    public final static String instancemethod___func___doc = 
+        "the function (or other callable) implementing a method";
+
+    public final static String instancemethod___get___doc = 
+        "descr.__get__(obj[, type]) -> value";
+
+    public final static String instancemethod___getattribute___doc = 
         "x.__getattribute__('name') <==> x.name";
 
-    public final static String code___gt___doc = 
-        "x.__gt__(y) <==> x>y";
-
-    public final static String code___hash___doc = 
+    public final static String instancemethod___hash___doc = 
         "x.__hash__() <==> hash(x)";
 
-    public final static String code___init___doc = 
+    public final static String instancemethod___init___doc = 
         "x.__init__(...) initializes x; see help(type(x)) for signature";
 
-    public final static String code___le___doc = 
-        "x.__le__(y) <==> x<=y";
-
-    public final static String code___lt___doc = 
-        "x.__lt__(y) <==> x<y";
-
-    public final static String code___ne___doc = 
-        "x.__ne__(y) <==> x!=y";
-
-    public final static String code___new___doc = 
+    public final static String instancemethod___new___doc = 
         "T.__new__(S, ...) -> a new object with type S, a subtype of T";
 
-    public final static String code___reduce___doc = 
+    public final static String instancemethod___reduce___doc = 
         "helper for pickle";
 
-    public final static String code___reduce_ex___doc = 
+    public final static String instancemethod___reduce_ex___doc = 
         "helper for pickle";
 
-    public final static String code___repr___doc = 
+    public final static String instancemethod___repr___doc = 
         "x.__repr__() <==> repr(x)";
 
-    public final static String code___setattr___doc = 
+    public final static String instancemethod___self___doc = 
+        "the instance to which a method is bound; None for unbound methods";
+
+    public final static String instancemethod___setattr___doc = 
         "x.__setattr__('name', value) <==> x.name = value";
 
-    public final static String code___sizeof___doc = 
+    public final static String instancemethod___sizeof___doc = 
         "__sizeof__() -> int\n" + 
         "size of object in memory, in bytes";
 
-    public final static String code___str___doc = 
+    public final static String instancemethod___str___doc = 
         "x.__str__() <==> str(x)";
 
-    public final static String code___subclasshook___doc = 
+    public final static String instancemethod___subclasshook___doc = 
         "Abstract classes can override this to customize issubclass().\n" + 
         "\n" + 
         "This is invoked early on by abc.ABCMeta.__subclasscheck__().\n" + 
@@ -4433,93 +4442,85 @@
         "overrides the normal algorithm (and the outcome is cached).\n" + 
         "";
 
-    public final static String code_co_argcount_doc = 
-        "";
-
-    public final static String code_co_cellvars_doc = 
-        "";
-
-    public final static String code_co_code_doc = 
-        "";
-
-    public final static String code_co_consts_doc = 
-        "";
-
-    public final static String code_co_filename_doc = 
-        "";
-
-    public final static String code_co_firstlineno_doc = 
-        "";
-
-    public final static String code_co_flags_doc = 
-        "";
-
-    public final static String code_co_freevars_doc = 
-        "";
-
-    public final static String code_co_lnotab_doc = 
-        "";
-
-    public final static String code_co_name_doc = 
-        "";
-
-    public final static String code_co_names_doc = 
-        "";
-
-    public final static String code_co_nlocals_doc = 
-        "";
-
-    public final static String code_co_stacksize_doc = 
-        "";
-
-    public final static String code_co_varnames_doc = 
-        "";
-
-    // Docs for <type 'frame'>
-    public final static String frame___class___doc = 
+    public final static String instancemethod_im_class_doc = 
+        "the class associated with a method";
+
+    public final static String instancemethod_im_func_doc = 
+        "the function (or other callable) implementing a method";
+
+    public final static String instancemethod_im_self_doc = 
+        "the instance to which a method is bound; None for unbound methods";
+
+    // Docs for <type 'code'>
+    public final static String code___class___doc = 
         "type(object) -> the object's type\n" + 
         "type(name, bases, dict) -> a new type";
 
-    public final static String frame___delattr___doc = 
+    public final static String code___cmp___doc = 
+        "x.__cmp__(y) <==> cmp(x,y)";
+
+    public final static String code___delattr___doc = 
         "x.__delattr__('name') <==> del x.name";
 
-    public final static String frame_doc = 
-        "";
-
-    public final static String frame___format___doc = 
+    public final static String code_doc = 
+        "code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n" + 
+        "      varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n" + 
+        "\n" + 
+        "Create a code object.  Not for the faint of heart.";
+
+    public final static String code___eq___doc = 
+        "x.__eq__(y) <==> x==y";
+
+    public final static String code___format___doc = 
         "default object formatter";
 
-    public final static String frame___getattribute___doc = 
+    public final static String code___ge___doc = 
+        "x.__ge__(y) <==> x>=y";
+
+    public final static String code___getattribute___doc = 
         "x.__getattribute__('name') <==> x.name";
 
-    public final static String frame___hash___doc = 
+    public final static String code___gt___doc = 
+        "x.__gt__(y) <==> x>y";
+
+    public final static String code___hash___doc = 
         "x.__hash__() <==> hash(x)";
 
-    public final static String frame___init___doc = 
+    public final static String code___init___doc = 
         "x.__init__(...) initializes x; see help(type(x)) for signature";
 
-    public final static String frame___new___doc = 
+    public final static String code___le___doc = 
+        "x.__le__(y) <==> x<=y";
+
+    public final static String code___lt___doc = 
+        "x.__lt__(y) <==> x<y";
+
+    public final static String code___ne___doc = 
+        "x.__ne__(y) <==> x!=y";
+
+    public final static String code___new___doc = 
         "T.__new__(S, ...) -> a new object with type S, a subtype of T";
 
-    public final static String frame___reduce___doc = 
+    public final static String code___reduce___doc = 
         "helper for pickle";
 
-    public final static String frame___reduce_ex___doc = 
+    public final static String code___reduce_ex___doc = 
         "helper for pickle";
 
-    public final static String frame___repr___doc = 
+    public final static String code___repr___doc = 
         "x.__repr__() <==> repr(x)";
 
-    public final static String frame___setattr___doc = 
+    public final static String code___setattr___doc = 
         "x.__setattr__('name', value) <==> x.name = value";
 
-    public final static String frame___sizeof___doc = 
-        "F.__sizeof__() -> size of F in memory, in bytes";
-
-    public final static String frame___str___doc = 
+    public final static String code___sizeof___doc = 
+        "__sizeof__() -> int\n" + 
+        "size of object in memory, in bytes";
+
+    public final static String code___str___doc = 
         "x.__str__() <==> str(x)";
 
-    public final static String frame___subclasshook___doc = 
+    public final static String code___subclasshook___doc = 
         "Abstract classes can override this to customize issubclass().\n" + 
         "\n" + 
         "This is invoked early on by abc.ABCMeta.__subclasscheck__().\n" + 
@@ -4528,88 +4529,93 @@
         "overrides the normal algorithm (and the outcome is cached).\n" + 
         "";
 
-    public final static String frame_f_back_doc = 
+    public final static String code_co_argcount_doc = 
         "";
 
-    public final static String frame_f_builtins_doc = 
+    public final static String code_co_cellvars_doc = 
         "";
 
-    public final static String frame_f_code_doc = 
+    public final static String code_co_code_doc = 
         "";
 
-    public final static String frame_f_exc_traceback_doc = 
+    public final static String code_co_consts_doc = 
         "";
 
-    public final static String frame_f_exc_type_doc = 
+    public final static String code_co_filename_doc = 
         "";
 
-    public final static String frame_f_exc_value_doc = 
+    public final static String code_co_firstlineno_doc = 
         "";
 
-    public final static String frame_f_globals_doc = 
+    public final static String code_co_flags_doc = 
         "";
 
-    public final static String frame_f_lasti_doc = 
+    public final static String code_co_freevars_doc = 
         "";
 
-    public final static String frame_f_lineno_doc = 
+    public final static String code_co_lnotab_doc = 
         "";
 
-    public final static String frame_f_locals_doc = 
+    public final static String code_co_name_doc = 
         "";
 
-    public final static String frame_f_restricted_doc = 
+    public final static String code_co_names_doc = 
         "";
 
-    public final static String frame_f_trace_doc = 
+    public final static String code_co_nlocals_doc = 
         "";
 
-    // Docs for <type 'traceback'>
-    public final static String traceback___class___doc = 
+    public final static String code_co_stacksize_doc = 
+        "";
+
+    public final static String code_co_varnames_doc = 
+        "";
+
+    // Docs for <type 'frame'>
+    public final static String frame___class___doc = 
         "type(object) -> the object's type\n" + 
         "type(name, bases, dict) -> a new type";
 
-    public final static String traceback___delattr___doc = 
+    public final static String frame___delattr___doc = 
         "x.__delattr__('name') <==> del x.name";
 
-    public final static String traceback_doc = 
+    public final static String frame_doc = 
         "";
 
-    public final static String traceback___format___doc = 
+    public final static String frame___format___doc = 
         "default object formatter";
 
-    public final static String traceback___getattribute___doc = 
+    public final static String frame___getattribute___doc = 
         "x.__getattribute__('name') <==> x.name";
 
-    public final static String traceback___hash___doc = 
+    public final static String frame___hash___doc = 
         "x.__hash__() <==> hash(x)";
 
-    public final static String traceback___init___doc = 
+    public final static String frame___init___doc = 
         "x.__init__(...) initializes x; see help(type(x)) for signature";
 
-    public final static String traceback___new___doc = 
+    public final static String frame___new___doc = 
         "T.__new__(S, ...) -> a new object with type S, a subtype of T";
 
-    public final static String traceback___reduce___doc = 
+    public final static String frame___reduce___doc = 
         "helper for pickle";
 
-    public final static String traceback___reduce_ex___doc = 
+    public final static String frame___reduce_ex___doc = 
         "helper for pickle";
 
-    public final static String traceback___repr___doc = 
+    public final static String frame___repr___doc = 
         "x.__repr__() <==> repr(x)";
 
-    public final static String traceback___setattr___doc = 
+    public final static String frame___setattr___doc = 
         "x.__setattr__('name', value) <==> x.name = value";
 
-    public final static String traceback___sizeof___doc = 
-        "__sizeof__() -> int\n" + 
-        "size of object in memory, in bytes";
-
-    public final static String traceback___str___doc = 
+    public final static String frame___sizeof___doc = 
+        "F.__sizeof__() -> size of F in memory, in bytes";
+
+    public final static String frame___str___doc = 
         "x.__str__() <==> str(x)";
 
-    public final static String traceback___subclasshook___doc = 
+    public final static String frame___subclasshook___doc = 
         "Abstract classes can override this to customize issubclass().\n" + 
         "\n" + 
         "This is invoked early on by abc.ABCMeta.__subclasscheck__().\n" + 
@@ -4618,6 +4624,96 @@
         "overrides the normal algorithm (and the outcome is cached).\n" + 
         "";
 
+    public final static String frame_f_back_doc = 
+        "";
+
+    public final static String frame_f_builtins_doc = 
+        "";
+
+    public final static String frame_f_code_doc = 
+        "";
+
+    public final static String frame_f_exc_traceback_doc = 
+        "";
+
+    public final static String frame_f_exc_type_doc = 
+        "";
+
+    public final static String frame_f_exc_value_doc = 
+        "";
+
+    public final static String frame_f_globals_doc = 
+        "";
+
+    public final static String frame_f_lasti_doc = 
+        "";
+
+    public final static String frame_f_lineno_doc = 
+        "";
+
+    public final static String frame_f_locals_doc = 
+        "";
+
+    public final static String frame_f_restricted_doc = 
+        "";
+
+    public final static String frame_f_trace_doc = 
+        "";
+
+    // Docs for <type 'traceback'>
+    public final static String traceback___class___doc = 
+        "type(object) -> the object's type\n" + 
+        "type(name, bases, dict) -> a new type";
+
+    public final static String traceback___delattr___doc = 
+        "x.__delattr__('name') <==> del x.name";
+
+    public final static String traceback_doc = 
+        "";
+
+    public final static String traceback___format___doc = 
+        "default object formatter";
+
+    public final static String traceback___getattribute___doc = 
+        "x.__getattribute__('name') <==> x.name";
+
+    public final static String traceback___hash___doc = 
+        "x.__hash__() <==> hash(x)";
+
+    public final static String traceback___init___doc = 
+        "x.__init__(...) initializes x; see help(type(x)) for signature";
+
+    public final static String traceback___new___doc = 
+        "T.__new__(S, ...) -> a new object with type S, a subtype of T";
+
+    public final static String traceback___reduce___doc = 
+        "helper for pickle";
+
+    public final static String traceback___reduce_ex___doc = 
+        "helper for pickle";
+
+    public final static String traceback___repr___doc = 
+        "x.__repr__() <==> repr(x)";
+
+    public final static String traceback___setattr___doc = 
+        "x.__setattr__('name', value) <==> x.name = value";
+
+    public final static String traceback___sizeof___doc = 
+        "__sizeof__() -> int\n" + 
+        "size of object in memory, in bytes";
+
+    public final static String traceback___str___doc = 
+        "x.__str__() <==> str(x)";
+
+    public final static String traceback___subclasshook___doc = 
+        "Abstract classes can override this to customize issubclass().\n" + 
+        "\n" + 
+        "This is invoked early on by abc.ABCMeta.__subclasscheck__().\n" + 
+        "It should return True, False or NotImplemented.  If it returns\n" + 
+        "NotImplemented, the normal algorithm is used.  Otherwise, it\n" + 
+        "overrides the normal algorithm (and the outcome is cached).\n" + 
+        "";
+
     public final static String traceback_tb_frame_doc = 
         "";
 
diff --git a/src/org/python/core/Py2kBuffer.java b/src/org/python/core/Py2kBuffer.java
new file mode 100644
--- /dev/null
+++ b/src/org/python/core/Py2kBuffer.java
@@ -0,0 +1,619 @@
+// Copyright (c) 2013 Jython Developers
+package org.python.core;
+
+import org.python.core.buffer.BaseBuffer;
+import org.python.core.buffer.SimpleStringBuffer;
+import org.python.core.util.StringUtil;
+import org.python.expose.ExposedMethod;
+import org.python.expose.ExposedNew;
+import org.python.expose.ExposedType;
+import org.python.expose.MethodType;
+
+/**
+ * Class implementing the Python <code>buffer</code> type. <code>buffer</code> is being superseded
+ * in Python 2.7 by <code>memoryview</code>, and is provided here to support legacy Python code. Use
+ * <code>memoryview</code> if you can. <code>buffer</code> and <code>memoryview</code> both wrap the
+ * same Jython buffer API, the one designed for <code>memoryview</code>, whereas in CPython the C
+ * APIs supporting each are different. Because of this, they may be applied to exactly the same
+ * underlying object types. Their behaviour differs in detail.
+ */
+ at ExposedType(name = "buffer", doc = BuiltinDocs.buffer_doc, base = PyObject.class,
+        isBaseType = false)
+public class Py2kBuffer extends PySequence implements BufferProtocol {
+
+    public static final PyType TYPE = PyType.fromClass(Py2kBuffer.class);
+
+    /** The underlying object on which the buffer was created. */
+    private final BufferProtocol object;
+    /** The offset (in bytes) into the offered object at which the buffer starts */
+    private final int offset;
+    /** Number of bytes to include in the buffer (or -1 for all available). */
+    private final int size;
+
+    /**
+     * Construct a Py2kBuffer from an object supporting the {@link BufferProtocol}. The
+     * <code>buffer</code> takes no lease on the <code>PyBuffer</code> at present, but for each
+     * action performed obtains a new one and releases it. (Major difference from
+     * <code>memoryview</code>.) Note that when <code>size=-1</code> is given, the buffer reflects
+     * the changing size of the underlying object.
+     * 
+     * @param object the object on which this is to be a buffer
+     * @param offset into the array exposed by the object (0 for start)
+     * @param size of the slice or -1 for all of the object
+     */
+    public Py2kBuffer(BufferProtocol object, int offset, int size) {
+        super(TYPE);
+
+        if (object instanceof Py2kBuffer) {
+            // Special behaviour when the source object is another of our kind.
+            Py2kBuffer source = (Py2kBuffer)object;
+            offset = source.offset + offset;
+            if (source.size >= 0) {
+                // The source imposes a size limit, or rather it imposes an end
+                int end = source.offset + source.size;
+                if (size < 0 || offset + size > end) {
+                    // We are asked for unlimited/excessive length, but must impose source end.
+                    size = end - offset;
+                }
+            }
+            // This will be a Py2kBuffer with the derived offset and size on the same object.
+            object = source.object;
+        }
+        this.object = object;
+        this.offset = offset;
+        this.size = size;
+    }
+
+    /**
+     * Every action on the <code>buffer</code> must obtain a new {@link PyBuffer} reflecting (this
+     * buffer's slice of) the contents of the backing object.
+     * 
+     * @return a <code>PyBuffer</code> onto the specified slice
+     */
+    private PyBuffer getBuffer() {
+        /*
+         * Ask for the full set of facilities (strides, indirect, etc.) from the object in case they
+         * are necessary for navigation, but only ask for read access. If the object is writable,
+         * the PyBuffer will be writable.
+         */
+        final int flags = PyBUF.FULL_RO;
+        PyBuffer buf = object.getBuffer(PyBUF.FULL_RO);
+
+        // This may already be what we need, or this buffer may be a sub-range of the object
+        if (offset > 0 || size >= 0) {
+            /*
+             * It's a sub-range so we have to construct a slice buffer on the first buffer. Take
+             * care that the bounds of the slice are within the object, which may have changed size
+             * since the buffer was created.
+             */
+            PyBuffer first = buf;
+            int start = offset;
+            int length = first.getLen() - start;
+
+            if (length <= 0) {
+                // Range now lies outside object: zero length slice
+                start = length = 0;
+            } else if (size >= 0 && size < length) {
+                // A size less than the available bytes was specified (size==-1 => all of them)
+                length = size;
+            }
+
+            // Now offset and length specify a feasible slice
+            buf = first.getBufferSlice(flags, offset, length);
+
+            // We should release our first lease because the slice buf holds one.
+            // That lease will be released when buf is released.
+            first.release();
+        }
+        return buf;
+    }
+
+    private static String[] paramNames = {"object", "offset", "size"};
+
+    @ExposedNew
+    static PyObject buffer_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args,
+            String[] keywords) {
+
+        // Use the ArgParser to access the arguments
+        ArgParser ap = new ArgParser("buffer", args, keywords, paramNames, 1);
+        PyObject obj = ap.getPyObject(0);
+        int offset = ap.getIndex(1, 0);
+        int size = ap.getInt(2, -1);
+
+        // Get the object as a BufferProtocol if possible
+        BufferProtocol object = null;
+        if (obj instanceof PyUnicode) {
+            /*
+             * Jython unicode does not support the buffer protocol (so that you can't take a
+             * memoryview of one). But to be compatible with CPython we allow buffer(unicode) to
+             * export two-byte UTF-16. Fortunately, a buffer is read-only, so we can use a copy.
+             */
+            String bytes = codecs.encode((PyString)obj, "UTF-16BE", "replace");
+            object = new PyString(bytes);
+
+        } else if (obj instanceof BufferProtocol) {
+                // That will do directly
+                object = (BufferProtocol)obj;
+
+        }
+
+        // Checks
+        if (object == null) {
+            throw Py.TypeError("object must support the buffer protocol (or be unicode)");
+        } else if (offset < 0) {
+            throw Py.ValueError("offset must be zero or positive");
+        } else if (size < -1) {
+            throw Py.ValueError("size must be zero or positive");
+        } else {
+            // Checks ok
+            return new Py2kBuffer(object, offset, size);
+        }
+    }
+
+    @Override
+    public int __len__() {
+        PyBuffer buf = getBuffer();
+        try {
+            return buf.getLen();
+        } finally {
+            buf.release();
+        }
+    }
+
+    @Override
+    public PyString __repr__() {
+        String fmt = "<read-only buffer for %s, size %d, offset %d at 0x%s>";
+        String ret = String.format(fmt, Py.idstr((PyObject)object), size, offset, Py.idstr(this));
+        return new PyString(ret);
+    }
+
+    @Override
+    public PyString __str__() {
+        PyBuffer buf = getBuffer();
+        try {
+            if (buf instanceof BaseBuffer) {
+                // In practice, it always is
+                return new PyString(buf.toString());
+            } else {
+                // But just in case ...
+                String s = StringUtil.fromBytes(buf);
+                return new PyString(s);
+            }
+        } finally {
+            buf.release();
+        }
+    }
+
+    /**
+     * Equivalent to the standard Python <code>__add__</code> method, that for a <code>buffer</code>
+     * treats it as a <code>str</code> ({@link PyString}) containing the same bytes.
+     */
+    @Override
+    public PyObject __add__(PyObject other) {
+        return buffer___add__(other);
+    }
+
+    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.buffer___add___doc)
+    final PyObject buffer___add__(PyObject other) {
+        return __str__().__add__(other);
+    }
+
+    /**
+     * Equivalent to the standard Python <code>__mul__</code> method, that for a <code>buffer</code>
+     * returns a <code>str</code> containing the same thing <code>n</code> times.
+     */
+    @Override
+    public PyObject __mul__(PyObject o) {
+        return buffer___mul__(o);
+    }
+
+    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.buffer___mul___doc)
+    final PyObject buffer___mul__(PyObject o) {
+        if (!o.isIndex()) {
+            return null;
+        }
+        return repeat(o.asIndex(Py.OverflowError));
+    }
+
+    /**
+     * Equivalent to the standard Python <code>__rmul__</code> method, that for a
+     * <code>buffer</code> returns a <code>str</code> containing the same thing <code>n</code>
+     * times.
+     */
+    @Override
+    public PyObject __rmul__(PyObject o) {
+        return buffer___rmul__(o);
+    }
+
+    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.buffer___rmul___doc)
+    final PyObject buffer___rmul__(PyObject o) {
+        if (!o.isIndex()) {
+            return null;
+        }
+        return repeat(o.asIndex(Py.OverflowError));
+    }
+
+    /*
+     * ============================================================================================
+     * Python API comparison operations
+     * ============================================================================================
+     */
+
+    /**
+     * Comparison function between two <code>buffer</code>s of bytes, returning 1, 0 or -1 as a>b,
+     * a==b, or a<b respectively. The comparison is by value, using Python unsigned byte
+     * conventions, left-to-right (low to high index). Zero bytes are significant, even at the end
+     * of the array: <code>[65,66,67]<"ABC\u0000"</code>, for example and <code>[]</code> is less
+     * than every non-empty b, while <code>[]==""</code>.
+     * 
+     * @param a left-hand wrapped array in the comparison
+     * @param b right-hand wrapped object in the comparison
+     * @return 1, 0 or -1 as a>b, a==b, or a<b respectively
+     */
+    private static int compare(PyBuffer a, PyBuffer b) {
+
+        // Compare elements one by one in these ranges:
+        int ap = 0;
+        int aEnd = ap + a.getLen();
+        int bp = 0;
+        int bEnd = b.getLen();
+
+        while (ap < aEnd) {
+            if (bp >= bEnd) {
+                // a is longer than b
+                return 1;
+            } else {
+                // Compare the corresponding bytes
+                int aVal = a.intAt(ap++);
+                int bVal = b.intAt(bp++);
+                int diff = aVal - bVal;
+                if (diff != 0) {
+                    return (diff < 0) ? -1 : 1;
+                }
+            }
+        }
+
+        // All the bytes matched and we reached the end of a
+        if (bp < bEnd) {
+            // But we didn't reach the end of b
+            return -1;
+        } else {
+            // And the end of b at the same time, so they're equal
+            return 0;
+        }
+    }
+
+    /**
+     * Comparison function between this <code>buffer</code> and any other object. The inequality
+     * comparison operators are based on this.
+     * 
+     * @param b
+     * @return 1, 0 or -1 as this>b, this==b, or this<b respectively, or -2 if the comparison is
+     *         not implemented
+     */
+    private int buffer_cmp(PyObject b) {
+
+        // Check the memeoryview is still alive: works here for all the inequalities
+        PyBuffer buf = getBuffer();
+        try {
+
+            // Try to get a byte-oriented view
+            PyBuffer bv = BaseBytes.getView(b);
+
+            if (bv == null) {
+                // Signifies a type mis-match. See PyObject._cmp_unsafe() and related code.
+                return -2;
+
+            } else {
+
+                try {
+                    if (bv == buf) {
+                        // Same buffer: quick result
+                        return 0;
+                    } else {
+                        // Actually compare the contents
+                        return compare(buf, bv);
+                    }
+
+                } finally {
+                    // Must always let go of the buffer
+                    bv.release();
+                }
+            }
+        } finally {
+            buf.release();
+        }
+
+    }
+
+    /**
+     * Fail-fast comparison function between byte array types and any other object, for when the
+     * test is only for equality. The inequality comparison operators <code>__eq__</code> and
+     * <code>__ne__</code> are based on this.
+     * 
+     * @param b
+     * @return 0 if this==b, or +1 or -1 if this!=b, or -2 if the comparison is not implemented
+     */
+    private int buffer_cmpeq(PyObject b) {
+
+        // Get a view on the underlying object
+        PyBuffer buf = getBuffer();
+        try {
+
+            // Try to get a byte-oriented view
+            PyBuffer bv = BaseBytes.getView(b);
+
+            if (bv == null) {
+                // Signifies a type mis-match. See PyObject._cmp_unsafe() and related code.
+                return -2;
+
+            } else {
+
+                try {
+                    if (bv == buf) {
+                        // Same buffer: quick result
+                        return 0;
+                    } else if (bv.getLen() != buf.getLen()) {
+                        // Different size: can't be equal, and we don't care which is bigger
+                        return 1;
+                    } else {
+                        // Actually compare the contents
+                        return compare(buf, bv);
+                    }
+
+                } finally {
+                    // Must always let go of the buffer
+                    bv.release();
+                }
+            }
+        } finally {
+            buf.release();
+        }
+
+    }
+
+    /*
+     * These strings are adapted from the patch in CPython issue 15855 and the on-line documentation
+     * most attributes do not come with any docstrings in CPython 2.7, so the make_pydocs trick
+     * won't work. This is a complete set, although not all are needed in Python 2.7.
+     */
+    private final static String tobytes_doc = "M.tobytes() -> bytes\n\n"
+            + "Return the data in the buffer as a bytestring (an object of class str).";
+
+    private final static String tolist_doc = "M.tolist() -> list\n\n"
+            + "Return the data in the buffer as a list of elements.";
+
+    /*
+     * ============================================================================================
+     * Support for the Buffer API
+     * ============================================================================================
+     */
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The {@link PyBuffer} returned from this method is provided directly by the underlying object
+     * on which this buffer was constructed, taking account of the slicing arguments (offset and
+     * size), if these were given when the buffer was constructed.
+     */
+    @Override
+    public PyBuffer getBuffer(int flags) {
+
+        // Get a simple buffer meeting the specification of tha caller
+        PyBuffer buf = object.getBuffer(flags);
+
+        // This may already be what we need, or this buffer may be a sub-range of the object
+        if (offset > 0 || size >= 0) {
+            /*
+             * It's a sub-range so we have to construct a slice buffer on the first buffer. Take
+             * care that the bounds of the slice are within the object, which may have changed size
+             * since the buffer was created.
+             */
+            PyBuffer first = buf;
+            int start = offset;
+            int length = first.getLen() - start;
+
+            if (length <= 0) {
+                // Range now lies outside object: zero length slice
+                start = length = 0;
+            } else if (size >= 0 && size < length) {
+                // A size less than the available bytes was specified (size==-1 => all of them)
+                length = size;
+            }
+
+            // Now offset and length specify a feasible slice
+            buf = first.getBufferSlice(flags, offset, length);
+
+            // We should release our first lease because the slice buf holds one.
+            // That lease will be released when buf is released.
+            first.release();
+        }
+        return buf;
+    }
+
+    /*
+     * ============================================================================================
+     * API for org.python.core.PySequence
+     * ============================================================================================
+     */
+    /**
+     * Gets the indexed element of the <code>buffer</code> as a one byte string. This is an
+     * extension point called by PySequence in its implementation of {@link #__getitem__}. It is
+     * guaranteed by PySequence that the index is within the bounds of the <code>buffer</code>.
+     * 
+     * @param index index of the element to get.
+     * @return one-character string formed from the byte at the index
+     */
+    @Override
+    protected PyString pyget(int index) {
+        // Our chance to check the buffer is still alive
+        PyBuffer buf = getBuffer();
+        try {
+            // Treat the byte at the index as a character code
+            return new PyString(String.valueOf((char)buf.intAt(index)));
+        } finally {
+            buf.release();
+        }
+    }
+
+    /**
+     * Returns a slice of elements from this sequence as a PyString.
+     * 
+     * @param start the position of the first element.
+     * @param stop one more than the position of the last element.
+     * @param step the step size.
+     * @return a PyString corresponding the the given range of elements.
+     */
+    @Override
+    protected synchronized PyString getslice(int start, int stop, int step) {
+        // Our chance to check the buffer is still alive
+        PyBuffer buf = getBuffer();
+        try {
+            int n = sliceLength(start, stop, step);
+            PyBuffer first = buf;
+            buf = first.getBufferSlice(PyBUF.FULL_RO, start, n, step);
+            first.release(); // We've finished (buf holds a lease)
+            PyString ret = Py.newString(buf.toString());
+            return ret;
+        } finally {
+            buf.release();
+        }
+    }
+
+    /**
+     * <code>buffer*int</code> represent repetition in Python, and returns a <code>str</code> (
+     * <code>bytes</code>) object.
+     * 
+     * @param count the number of times to repeat this.
+     * @return a PyString repeating this buffer (as a <code>str</code>) that many times
+     */
+    @Override
+    protected synchronized PyString repeat(int count) {
+        PyBuffer buf = getBuffer();
+        try {
+            PyString ret = Py.newString(buf.toString());
+            return (PyString)ret.repeat(count);
+        } finally {
+            buf.release();
+        }
+    }
+
+    /**
+     * Sets the indexed element of the <code>buffer</code> to the given value, treating the
+     * operation as assignment to a slice of length one. This is different from the same operation
+     * on a byte array, where the assigned value must be an int: here it must have the buffer API
+     * and length one. This is an extension point called by PySequence in its implementation of
+     * {@link #__setitem__} It is guaranteed by PySequence that the index is within the bounds of
+     * the <code>buffer</code>. Any other clients calling <tt>pyset(int, PyObject)</tt> must make
+     * the same guarantee.
+     * 
+     * @param index index of the element to set.
+     * @param value to set this element to, regarded as a buffer of length one unit.
+     * @throws PyException(AttributeError) if value cannot be converted to an integer
+     * @throws PyException(ValueError) if value<0 or value>255
+     */
+    @Override
+    public synchronized void pyset(int index, PyObject value) throws PyException {
+        // Our chance to check the buffer is still alive
+        PyBuffer buf = getBuffer();
+        try {
+
+            // Get a buffer API on the value being assigned
+            PyBuffer valueBuf = BaseBytes.getViewOrError(value);
+            try {
+                if (valueBuf.getLen() != 1) {
+                    // CPython 2.7 message
+                    throw Py.ValueError("cannot modify size of buffer object");
+                }
+                buf.storeAt(valueBuf.byteAt(0), index);
+            } finally {
+                valueBuf.release();
+            }
+        } finally {
+            buf.release();
+        }
+    }
+
+    /**
+     * Sets the given range of elements according to Python slice assignment semantics. If the step
+     * size is one, it is a simple slice and the operation is equivalent to replacing that slice,
+     * with the value, accessing the value via the buffer protocol.
+     * 
+     * <pre>
+     * a = bytearray(b'abcdefghijklmnopqrst')
+     * m = buffer(a)
+     * m[2:7] = "ABCDE"
+     * </pre>
+     * 
+     * Results in <code>a=bytearray(b'abABCDEhijklmnopqrst')</code>.
+     * <p>
+     * If the step size is one, but stop-start does not match the length of the right-hand-side a
+     * ValueError is thrown.
+     * <p>
+     * If the step size is not one, and start!=stop, the slice defines a certain number of elements
+     * to be replaced. This function is not available in Python 2.7 (but it is in Python 3.3).
+     * <p>
+     * 
+     * <pre>
+     * a = bytearray(b'abcdefghijklmnopqrst')
+     * a[2:12:2] = iter( [65, 66, 67, long(68), "E"] )
+     * </pre>
+     * 
+     * Results in <code>a=bytearray(b'abAdBfChDjElmnopqrst')</code> in Python 3.3.
+     * 
+     * @param start the position of the first element.
+     * @param stop one more than the position of the last element.
+     * @param step the step size.
+     * @param value an object consistent with the slice assignment
+     */
+    @Override
+    protected synchronized void setslice(int start, int stop, int step, PyObject value) {
+        // Our chance to check the buffer is still alive
+        PyBuffer buf = getBuffer();
+        try {
+
+            if (step == 1 && stop < start) {
+                // Because "b[5:2] = v" means insert v just before 5 not 2.
+                // ... although "b[5:2:-1] = v means b[5]=v[0], b[4]=v[1], b[3]=v[2]
+                stop = start;
+            }
+
+            // Get a buffer API on the value being assigned
+            PyBuffer valueBuf = BaseBytes.getViewOrError(value);
+
+            // We'll also regard the assigned slice as a buffer.
+            PyBuffer bufSlice = null;
+
+            try {
+                // How many destination items? Has to match size of value.
+                int n = sliceLength(start, stop, step);
+                if (n != valueBuf.getLen()) {
+                    // CPython 2.7 message
+                    throw Py.ValueError("cannot modify size of buffer object");
+                }
+
+                /*
+                 * In the next section, we get a sliced view of the buf and write the value to it.
+                 * The approach to errors is unusual for compatibility with CPython. We pretend we
+                 * will not need a WRITABLE buffer in order to avoid throwing a BufferError. This
+                 * does not stop the returned object being writable, simply avoids the check. If in
+                 * fact it is read-only, then trying to write raises TypeError.
+                 */
+
+                bufSlice = buf.getBufferSlice(PyBUF.FULL_RO, start, n, step);
+                bufSlice.copyFrom(valueBuf);
+
+            } finally {
+
+                // Release the buffers we obtained (if we did)
+                if (bufSlice != null) {
+                    bufSlice.release();
+                }
+                valueBuf.release();
+            }
+        } finally {
+            buf.release();
+        }
+    }
+
+}
diff --git a/src/org/python/core/PyUnicode.java b/src/org/python/core/PyUnicode.java
--- a/src/org/python/core/PyUnicode.java
+++ b/src/org/python/core/PyUnicode.java
@@ -428,20 +428,33 @@
         }
     }
 
+    /**
+     * Helper used many times to "coerce" a method argument into a <code>PyUnicode</code> (which it
+     * may already be). A <code>null</code> argument or a <code>PyNone</code> causes
+     * <code>null</code> to be returned.
+     *
+     * @param o the object to coerce
+     * @return an equivalent <code>PyUnicode</code> (or o itself, or <code>null</code>)
+     */
     private PyUnicode coerceToUnicode(PyObject o) {
         if (o == null) {
             return null;
         } else if (o instanceof PyUnicode) {
-            return (PyUnicode) o;
-        } else if (o instanceof PyString) {
-            return new PyUnicode(o.toString());
+            return (PyUnicode)o;
         } else if (o == Py.None) {
             return null;
+        } else if (o instanceof BufferProtocol) {
+            // PyString or PyByteArray, PyMemoryView, Py2kBuffer ...
+            PyBuffer buf = ((BufferProtocol)o).getBuffer(PyBUF.FULL_RO);
+            try {
+                return new PyUnicode(buf.toString());
+            } finally {
+                buf.release();
+            }
         } else {
-            throw Py.TypeError("coercing to Unicode: need string or buffer, " +
-                    o.getType().fastGetName() + "found");
+            throw Py.TypeError("coercing to Unicode: need string or buffer, "
+                    + o.getType().fastGetName() + " found");
         }
-
     }
 
     @ExposedMethod(doc = BuiltinDocs.unicode___contains___doc)
diff --git a/src/org/python/core/__builtin__.java b/src/org/python/core/__builtin__.java
--- a/src/org/python/core/__builtin__.java
+++ b/src/org/python/core/__builtin__.java
@@ -294,6 +294,7 @@
         dict.__setitem__("False", Py.False);
         dict.__setitem__("bytes", PyString.TYPE);
         dict.__setitem__("bytearray", PyByteArray.TYPE);
+        dict.__setitem__("buffer", Py2kBuffer.TYPE);
         dict.__setitem__("memoryview", PyMemoryView.TYPE);
 
         // Work in debug mode by default
diff --git a/src/org/python/core/buffer/SimpleStringBuffer.java b/src/org/python/core/buffer/SimpleStringBuffer.java
--- a/src/org/python/core/buffer/SimpleStringBuffer.java
+++ b/src/org/python/core/buffer/SimpleStringBuffer.java
@@ -90,8 +90,14 @@
      */
     @Override
     public PyBuffer getBufferSlice(int flags, int start, int length) {
-        // The new string content is just a sub-string. (Non-copy operation in Java.)
-        return new SimpleStringView(getRoot(), flags, bufString.substring(start, start + length));
+        if (length > 0) {
+            // The new string content is just a sub-string. (Non-copy operation in Java.)
+            return new SimpleStringView(getRoot(), flags,
+                    bufString.substring(start, start + length));
+        } else {
+            // Special case for length==0 where start out of bounds sometimes raises exception.
+            return new ZeroByteBuffer.View(getRoot(), flags);
+        }
     }
 
     /**

-- 
Repository URL: http://hg.python.org/jython


More information about the Jython-checkins mailing list