[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