[Jython-checkins] jython: Add to PyBuffer a reference to the exporting object.
jeff.allen
jython-checkins at python.org
Sat Aug 27 09:12:25 EDT 2016
https://hg.python.org/jython/rev/59e3bae3c519
changeset: 7948:59e3bae3c519
user: Jeff Allen <ja.py at farowl.co.uk>
date: Mon Jul 11 13:33:02 2016 +0100
summary:
Add to PyBuffer a reference to the exporting object.
A getObj() method is added to the interface (emulating the CPython obj
member), and is added to constructors for concrete implementations
provided in the org.python.core.buffer package.
files:
src/org/python/core/PyArray.java | 9 +-
src/org/python/core/PyBuffer.java | 8 ++
src/org/python/core/PyByteArray.java | 2 +-
src/org/python/core/PyMemoryView.java | 17 +++-
src/org/python/core/PyString.java | 2 +-
src/org/python/core/buffer/BaseBuffer.java | 11 +++
src/org/python/core/buffer/BaseNIOBuffer.java | 2 -
src/org/python/core/buffer/SimpleBuffer.java | 29 +++++---
src/org/python/core/buffer/SimpleNIOBuffer.java | 29 +++++---
src/org/python/core/buffer/SimpleStringBuffer.java | 10 +-
src/org/python/core/buffer/SimpleWritableBuffer.java | 16 ++-
src/org/python/core/buffer/Strided1DBuffer.java | 12 ++-
src/org/python/core/buffer/Strided1DNIOBuffer.java | 17 +++-
src/org/python/core/buffer/Strided1DWritableBuffer.java | 11 ++-
src/org/python/core/buffer/ZeroByteBuffer.java | 8 +-
src/org/python/modules/_io/PyIOBase.java | 9 +-
tests/java/org/python/core/BaseBytesTest.java | 7 +-
tests/java/org/python/core/PyBufferNIOTest.java | 22 +++--
tests/java/org/python/core/PyBufferTest.java | 34 ++++++---
19 files changed, 163 insertions(+), 92 deletions(-)
diff --git a/src/org/python/core/PyArray.java b/src/org/python/core/PyArray.java
--- a/src/org/python/core/PyArray.java
+++ b/src/org/python/core/PyArray.java
@@ -2081,10 +2081,10 @@
// This is byte data, so we are within the state of the art
byte[] storage = (byte[])data;
int size = delegate.getSize();
- pybuf = new SimpleWritableBuffer(flags, storage, 0, size);
+ pybuf = new SimpleWritableBuffer(flags, this, storage, 0, size);
} else if ((flags & PyBUF.WRITABLE) == 0) {
// As the client only intends to read, fake the answer with a String
- pybuf = new SimpleStringBuffer(flags, tostring());
+ pybuf = new SimpleStringBuffer(flags, this, tostring());
} else {
// For the time being ...
throw Py.NotImplementedError("only array('b') can export a writable buffer");
@@ -2163,7 +2163,6 @@
return buf.remaining();
}
-
@Override
public int read() {
return buf.hasRemaining() ? buf.get() & 0xff : -1;
@@ -2187,7 +2186,6 @@
}
}
-
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
@@ -2198,8 +2196,7 @@
}
@Override
- public boolean refersDirectlyTo(PyObject ob)
- throws UnsupportedOperationException {
+ public boolean refersDirectlyTo(PyObject ob) throws UnsupportedOperationException {
if (data == null || !gc.canLinkToPyObject(data.getClass(), true)) {
return false;
}
diff --git a/src/org/python/core/PyBuffer.java b/src/org/python/core/PyBuffer.java
--- a/src/org/python/core/PyBuffer.java
+++ b/src/org/python/core/PyBuffer.java
@@ -30,6 +30,14 @@
// int getLen();
/**
+ * Return the underlying exporting object (or <code>null</code> if no object implementing the
+ * {@link BufferProtocol} is in that role). This will often be a <code>PyObject</code>.
+ *
+ * @return exporting object (or <code>null</code>)
+ */
+ BufferProtocol getObj();
+
+ /**
* Return the byte indexed from a one-dimensional buffer with item size one. This is part of the
* fully-encapsulated API: the buffer implementation exported takes care of navigating the
* structure of the buffer. Results are undefined where the number of dimensions is not one or
diff --git a/src/org/python/core/PyByteArray.java b/src/org/python/core/PyByteArray.java
--- a/src/org/python/core/PyByteArray.java
+++ b/src/org/python/core/PyByteArray.java
@@ -228,7 +228,7 @@
if (pybuf == null) {
// No existing export we can re-use: create a new one
- pybuf = new SimpleWritableBuffer(flags, storage, offset, size);
+ pybuf = new SimpleWritableBuffer(flags, this, storage, offset, size);
// Hold a reference for possible re-use
export = new WeakReference<BaseBuffer>(pybuf);
}
diff --git a/src/org/python/core/PyMemoryView.java b/src/org/python/core/PyMemoryView.java
--- a/src/org/python/core/PyMemoryView.java
+++ b/src/org/python/core/PyMemoryView.java
@@ -75,6 +75,13 @@
}
}
+ // @ExposedGet(doc = obj_doc) // Not exposed in Python 2.7
+ public PyObject obj() {
+ checkNotReleased();
+ BufferProtocol obj = backing.getObj();
+ return (obj instanceof PyObject) ? (PyObject)obj : Py.None;
+ }
+
@ExposedGet(doc = format_doc)
public String format() {
checkNotReleased();
@@ -843,19 +850,18 @@
}
}
-
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
int retVal;
if (backing != null) {
if (backing instanceof PyObject) {
- retVal = visit.visit((PyObject) backing, arg);
+ retVal = visit.visit((PyObject)backing, arg);
if (retVal != 0) {
return retVal;
}
} else if (backing instanceof Traverseproc) {
- retVal = ((Traverseproc) backing).traverse(visit, arg);
+ retVal = ((Traverseproc)backing).traverse(visit, arg);
if (retVal != 0) {
return retVal;
}
@@ -878,11 +884,10 @@
@Override
public boolean refersDirectlyTo(PyObject ob) {
- if (ob != null && (ob == backing || ob == shape || ob == strides
- || ob == suboffsets)) {
+ if (ob != null && (ob == backing || ob == shape || ob == strides || ob == suboffsets)) {
return true;
} else if (suboffsets instanceof Traverseproc) {
- return ((Traverseproc) suboffsets).refersDirectlyTo(ob);
+ return ((Traverseproc)suboffsets).refersDirectlyTo(ob);
} else {
return false;
}
diff --git a/src/org/python/core/PyString.java b/src/org/python/core/PyString.java
--- a/src/org/python/core/PyString.java
+++ b/src/org/python/core/PyString.java
@@ -204,7 +204,7 @@
* No existing export we can re-use. Return a buffer, but specialised to defer
* construction of the buf object, and cache a soft reference to it.
*/
- pybuf = new SimpleStringBuffer(flags, getString());
+ pybuf = new SimpleStringBuffer(flags, this, getString());
export = new SoftReference<BaseBuffer>(pybuf);
}
return pybuf;
diff --git a/src/org/python/core/buffer/BaseBuffer.java b/src/org/python/core/buffer/BaseBuffer.java
--- a/src/org/python/core/buffer/BaseBuffer.java
+++ b/src/org/python/core/buffer/BaseBuffer.java
@@ -45,6 +45,12 @@
public abstract class BaseBuffer implements PyBuffer {
/**
+ * The object that exported this buffer (or <code>null</code> if the subclass or exporter
+ * chooses not to supply a reference).
+ */
+ protected BufferProtocol obj;
+
+ /**
* The dimensions of the array represented by the buffer. The length of the <code>shape</code>
* array is the number of dimensions. The <code>shape</code> array should always be created and
* filled (difference from CPython). This value is returned by {@link #getShape()}.
@@ -255,6 +261,11 @@
return len;
}
+ @Override
+ public final BufferProtocol getObj() {
+ return obj;
+ }
+
/**
* Retrieve the byte at the given index in the underlying storage treated as a flat sequence of
* bytes. This byte-index will have been computed from the item index (which may have been
diff --git a/src/org/python/core/buffer/BaseNIOBuffer.java b/src/org/python/core/buffer/BaseNIOBuffer.java
--- a/src/org/python/core/buffer/BaseNIOBuffer.java
+++ b/src/org/python/core/buffer/BaseNIOBuffer.java
@@ -5,7 +5,6 @@
import java.nio.ReadOnlyBufferException;
import org.python.core.PyBUF;
-import org.python.core.PyBuffer;
import org.python.core.PyException;
/**
@@ -50,7 +49,6 @@
* @param size number of elements in the view
* @param stride byte-index step between successive elements
*/
-
protected BaseNIOBuffer(ByteBuffer storage, int featureFlags, int index0, int size, int stride) {
super(featureFlags & ~(WRITABLE | AS_ARRAY), index0, size, stride);
this.storage = storage;
diff --git a/src/org/python/core/buffer/SimpleBuffer.java b/src/org/python/core/buffer/SimpleBuffer.java
--- a/src/org/python/core/buffer/SimpleBuffer.java
+++ b/src/org/python/core/buffer/SimpleBuffer.java
@@ -1,5 +1,6 @@
package org.python.core.buffer;
+import org.python.core.BufferProtocol;
import org.python.core.PyBuffer;
import org.python.core.PyException;
import org.python.core.util.StringUtil;
@@ -22,14 +23,16 @@
* checkRequestFlags(flags); // Check request is compatible with type
* </pre>
*
+ * @param obj exporting object (or <code>null</code>)
* @param storage the array of bytes storing the implementation of the exporting object
* @param index0 offset where the data starts in that array (item[0])
* @param size the number of bytes occupied
* @throws NullPointerException if <code>storage</code> is null
*/
- protected SimpleBuffer(byte[] storage, int index0, int size) throws PyException,
- ArrayIndexOutOfBoundsException {
+ protected SimpleBuffer(BufferProtocol obj, byte[] storage, int index0, int size)
+ throws PyException, ArrayIndexOutOfBoundsException {
super(storage, CONTIGUITY | SIMPLE, index0, size, 1);
+ this.obj = obj;
}
/**
@@ -38,6 +41,7 @@
* against the capabilities of the buffer type.
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage the array of bytes storing the implementation of the exporting object
* @param index0 offset where the data starts in that array (item[0])
* @param size the number of bytes occupied
@@ -46,10 +50,10 @@
* inconsistent with <code>storage.length</code>
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public SimpleBuffer(int flags, byte[] storage, int index0, int size) throws PyException,
- ArrayIndexOutOfBoundsException, NullPointerException {
- this(storage, index0, size); // Construct checked SimpleBuffer
- checkRequestFlags(flags); // Check request is compatible with type
+ public SimpleBuffer(int flags, BufferProtocol obj, byte[] storage, int index0, int size)
+ throws PyException, ArrayIndexOutOfBoundsException, NullPointerException {
+ this(obj, storage, index0, size); // Construct checked SimpleBuffer
+ checkRequestFlags(flags); // Check request is compatible with type
// Check arguments using the "all non-negative" trick
if ((index0 | size | storage.length - (index0 + size)) < 0) {
throw new ArrayIndexOutOfBoundsException();
@@ -62,11 +66,12 @@
* {@link #index0}), and the navigation ({@link #shape} array) will be initialised from the
* array argument.
*
+ * @param obj exporting object (or <code>null</code>)
* @param storage the array of bytes storing the implementation of the exporting object
* @throws NullPointerException if <code>storage</code> is null
*/
- protected SimpleBuffer(byte[] storage) throws NullPointerException {
- this(storage, 0, storage.length);
+ protected SimpleBuffer(BufferProtocol obj, byte[] storage) throws NullPointerException {
+ this(obj, storage, 0, storage.length);
}
/**
@@ -75,12 +80,14 @@
* against the capabilities of the buffer type.
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage the array of bytes storing the implementation of the exporting object
* @throws NullPointerException if <code>storage</code> is null
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public SimpleBuffer(int flags, byte[] storage) throws PyException, NullPointerException {
- this(storage); // Construct SimpleBuffer on whole array
+ public SimpleBuffer(int flags, BufferProtocol obj, byte[] storage) throws PyException,
+ NullPointerException {
+ this(obj, storage); // Construct SimpleBuffer on whole array
checkRequestFlags(flags); // Check request is compatible with type
}
@@ -189,7 +196,7 @@
*/
public SimpleView(PyBuffer root, int flags, byte[] storage, int offset, int size) {
// Create a new SimpleBuffer on the buffer passed in (part of the root)
- super(flags, storage, offset, size);
+ super(flags, root.getObj(), storage, offset, size);
// Get a lease on the root PyBuffer
this.root = root.getBuffer(FULL_RO);
}
diff --git a/src/org/python/core/buffer/SimpleNIOBuffer.java b/src/org/python/core/buffer/SimpleNIOBuffer.java
--- a/src/org/python/core/buffer/SimpleNIOBuffer.java
+++ b/src/org/python/core/buffer/SimpleNIOBuffer.java
@@ -2,6 +2,7 @@
import java.nio.ByteBuffer;
+import org.python.core.BufferProtocol;
import org.python.core.PyBuffer;
import org.python.core.PyException;
@@ -29,6 +30,7 @@
* checkRequestFlags(flags); // Check request is compatible with type
* </pre>
*
+ * @param obj exporting object (or <code>null</code>)
* @param storage the <code>ByteBuffer</code> wrapping the exported object state. NOTE: this
* <code>PyBuffer</code> keeps a reference and may manipulate the position, mark and
* limit hereafter. Use {@link ByteBuffer#duplicate()} to give it an isolated copy.
@@ -38,9 +40,10 @@
* @throws ArrayIndexOutOfBoundsException if <code>index0</code> and <code>size</code> are
* inconsistent with <code>storage.capacity()</code>
*/
- protected SimpleNIOBuffer(ByteBuffer storage, int index0, int size) throws PyException,
- ArrayIndexOutOfBoundsException {
+ protected SimpleNIOBuffer(BufferProtocol obj, ByteBuffer storage, int index0, int size)
+ throws PyException, ArrayIndexOutOfBoundsException {
super(storage, CONTIGUITY | SIMPLE, index0, size, 1);
+ this.obj = obj;
// Check arguments using the "all non-negative" trick
if ((index0 | size | storage.capacity() - (index0 + size)) < 0) {
throw new ArrayIndexOutOfBoundsException();
@@ -54,6 +57,7 @@
* <code>ByteBuffer</code> passed in. (It is duplicated.)
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage the <code>ByteBuffer</code> wrapping the exported object state
* @param index0 offset where the data starts in that buffer (item[0])
* @param size the number of bytes occupied
@@ -62,10 +66,10 @@
* inconsistent with <code>storage.length</code>
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public SimpleNIOBuffer(int flags, ByteBuffer storage, int index0, int size) throws PyException,
- ArrayIndexOutOfBoundsException, NullPointerException {
- this(storage.duplicate(), index0, size); // Construct checked SimpleNIOBuffer
- checkRequestFlags(flags); // Check request is compatible with type
+ public SimpleNIOBuffer(int flags, BufferProtocol obj, ByteBuffer storage, int index0, int size)
+ throws PyException, ArrayIndexOutOfBoundsException, NullPointerException {
+ this(obj, storage.duplicate(), index0, size); // Construct checked SimpleNIOBuffer
+ checkRequestFlags(flags); // Check request is compatible with type
}
/**
@@ -74,13 +78,14 @@
* {@link #index0}), and the navigation ({@link #shape} array) will be initialised from the
* argument.
*
+ * @param obj exporting object (or <code>null</code>)
* @param storage the <code>ByteBuffer</code> wrapping the exported object state. NOTE: this
* <code>PyBuffer</code> keeps a reference and may manipulate the position, mark and
* limit hereafter. Use {@link ByteBuffer#duplicate()} to give it an isolated copy.
* @throws NullPointerException if <code>storage</code> is null
*/
- protected SimpleNIOBuffer(ByteBuffer storage) throws NullPointerException {
- this(storage, 0, storage.capacity());
+ protected SimpleNIOBuffer(BufferProtocol obj, ByteBuffer storage) throws NullPointerException {
+ this(obj, storage, 0, storage.capacity());
}
/**
@@ -90,12 +95,14 @@
* <code>ByteBuffer</code> passed in. (It is duplicated.)
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage the <code>ByteBuffer</code> wrapping the exported object state
* @throws NullPointerException if <code>storage</code> is null
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public SimpleNIOBuffer(int flags, ByteBuffer storage) throws PyException, NullPointerException {
- this(storage.duplicate()); // Construct SimpleNIOBuffer on whole ByteBuffer
+ public SimpleNIOBuffer(int flags, BufferProtocol obj, ByteBuffer storage) throws PyException,
+ NullPointerException {
+ this(obj, storage.duplicate()); // Construct SimpleNIOBuffer on whole ByteBuffer
checkRequestFlags(flags); // Check request is compatible with type
}
@@ -176,7 +183,7 @@
*/
public SimpleView(PyBuffer root, int flags, ByteBuffer storage, int offset, int count) {
// Create a new SimpleNIOBuffer on the buffer passed in (part of the root)
- super(flags, storage, offset, count);
+ super(flags, root.getObj(), storage, offset, count);
// Get a lease on the root PyBuffer
this.root = root.getBuffer(FULL_RO);
}
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
@@ -2,6 +2,7 @@
import java.nio.ByteBuffer;
+import org.python.core.BufferProtocol;
import org.python.core.PyBuffer;
import org.python.core.util.StringUtil;
@@ -26,15 +27,16 @@
* Provide an instance of SimpleStringBuffer meeting the consumer's expectations as expressed in
* the flags argument.
*
+ * @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param bufString storing the implementation of the object
- * @param flags consumer requirements
*/
- public SimpleStringBuffer(int flags, String bufString) {
+ public SimpleStringBuffer(int flags, BufferProtocol obj, String bufString) {
/*
* Leaving storage=null is ok because we carefully override every method that uses it,
* deferring creation of the storage byte array until we absolutely must have one.
*/
- super(null, 0, bufString.length());
+ super(obj, null, 0, bufString.length());
// Save the backing string
this.bufString = bufString;
// Check request is compatible with type
@@ -205,7 +207,7 @@
*/
public SimpleStringView(PyBuffer root, int flags, String bufString) {
// Create a new SimpleStringBuffer on the string passed in
- super(flags, bufString);
+ super(flags, root.getObj(), bufString);
// Get a lease on the root PyBuffer
this.root = root.getBuffer(FULL_RO);
}
diff --git a/src/org/python/core/buffer/SimpleWritableBuffer.java b/src/org/python/core/buffer/SimpleWritableBuffer.java
--- a/src/org/python/core/buffer/SimpleWritableBuffer.java
+++ b/src/org/python/core/buffer/SimpleWritableBuffer.java
@@ -1,5 +1,6 @@
package org.python.core.buffer;
+import org.python.core.BufferProtocol;
import org.python.core.PyBuffer;
import org.python.core.PyException;
@@ -14,16 +15,17 @@
* against the capabilities of the buffer type.
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage the array of bytes storing the implementation of the exporting object
* @param index0 offset where the data starts in that array (item[0])
* @param size the number of bytes occupied
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public SimpleWritableBuffer(int flags, byte[] storage, int index0, int size)
+ public SimpleWritableBuffer(int flags, BufferProtocol obj, byte[] storage, int index0, int size)
throws PyException, NullPointerException {
- super(storage, index0, size); // Construct checked SimpleBuffer
+ super(obj, storage, index0, size); // Construct checked SimpleBuffer
addFeatureFlags(WRITABLE);
- checkRequestFlags(flags); // Check request is compatible with type
+ checkRequestFlags(flags); // Check request is compatible with type
}
/**
@@ -32,11 +34,13 @@
* checked against the capabilities of the buffer type.
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage the array of bytes storing the implementation of the exporting object
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public SimpleWritableBuffer(int flags, byte[] storage) throws PyException, NullPointerException {
- this(flags, storage, 0, storage.length);
+ public SimpleWritableBuffer(int flags, BufferProtocol obj, byte[] storage) throws PyException,
+ NullPointerException {
+ this(flags, obj, storage, 0, storage.length);
}
/**
@@ -121,7 +125,7 @@
*/
public SimpleView(PyBuffer root, int flags, byte[] storage, int index0, int size) {
// Create a new SimpleBuffer on the buffer passed in (part of the root)
- super(flags, storage, index0, size);
+ super(flags, root.getObj(), storage, index0, size);
// Get a lease on the root PyBuffer
this.root = root.getBuffer(FULL_RO);
}
diff --git a/src/org/python/core/buffer/Strided1DBuffer.java b/src/org/python/core/buffer/Strided1DBuffer.java
--- a/src/org/python/core/buffer/Strided1DBuffer.java
+++ b/src/org/python/core/buffer/Strided1DBuffer.java
@@ -1,5 +1,6 @@
package org.python.core.buffer;
+import org.python.core.BufferProtocol;
import org.python.core.PyBuffer;
import org.python.core.PyException;
@@ -48,6 +49,7 @@
* {@link Strided1DWritableBuffer#Strided1DWritableBuffer(int, byte[], int, int, int)} for an
* example of this use.)
*
+ * @param obj exporting object (or <code>null</code>)
* @param storage raw byte array containing exported data
* @param index0 index into storage of item[0]
* @param count number of items in the slice
@@ -56,9 +58,10 @@
* @throws ArrayIndexOutOfBoundsException if <code>index0</code>, <code>count</code> and
* <code>stride</code> are inconsistent with <code>storage.length</code>
*/
- protected Strided1DBuffer(byte[] storage, int index0, int count, int stride)
+ protected Strided1DBuffer(BufferProtocol obj, byte[] storage, int index0, int count, int stride)
throws ArrayIndexOutOfBoundsException, NullPointerException {
super(storage, STRIDES, index0, count, stride);
+ this.obj = obj;
this.stride = stride; // Between items
if (count == 0) {
@@ -107,6 +110,7 @@
* <code>storage</code> array (unless <code>count=0</code>).
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage raw byte array containing exported data
* @param index0 index into storage of item[0]
* @param count number of items in the slice
@@ -116,9 +120,9 @@
* <code>stride</code> are inconsistent with <code>storage.length</code>
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public Strided1DBuffer(int flags, byte[] storage, int index0, int count, int stride)
+ public Strided1DBuffer(int flags, BufferProtocol obj, byte[] storage, int index0, int count, int stride)
throws ArrayIndexOutOfBoundsException, NullPointerException, PyException {
- this(storage, index0, count, stride);
+ this(obj, storage, index0, count, stride);
checkRequestFlags(flags); // Check request is compatible with type
}
@@ -199,7 +203,7 @@
public SlicedView(PyBuffer root, int flags, byte[] storage, int index0, int count,
int stride) throws PyException {
// Create a new on the buffer passed in (part of the root)
- super(flags, storage, index0, count, stride);
+ super(flags, root.getObj(), storage, index0, count, stride);
// Get a lease on the root PyBuffer (read-only)
this.root = root.getBuffer(FULL_RO);
}
diff --git a/src/org/python/core/buffer/Strided1DNIOBuffer.java b/src/org/python/core/buffer/Strided1DNIOBuffer.java
--- a/src/org/python/core/buffer/Strided1DNIOBuffer.java
+++ b/src/org/python/core/buffer/Strided1DNIOBuffer.java
@@ -2,6 +2,7 @@
import java.nio.ByteBuffer;
+import org.python.core.BufferProtocol;
import org.python.core.PyBuffer;
import org.python.core.PyException;
@@ -50,6 +51,7 @@
* {@link Strided1DWritableBuffer#Strided1DWritableBuffer(int, ByteBuffer, int, int, int)} for
* an example of this use.)
*
+ * @param obj exporting object (or <code>null</code>)
* @param storage the <code>ByteBuffer</code> wrapping the exported object state. NOTE: this
* <code>PyBuffer</code> keeps a reference and may manipulate the position, mark and
* limit hereafter. Use {@link ByteBuffer#duplicate()} to give it an isolated copy.
@@ -60,9 +62,10 @@
* @throws ArrayIndexOutOfBoundsException if <code>index0</code>, <code>count</code> and
* <code>stride</code> are inconsistent with <code>storage.length</code>
*/
- protected Strided1DNIOBuffer(ByteBuffer storage, int index0, int count, int stride)
- throws ArrayIndexOutOfBoundsException, NullPointerException {
+ protected Strided1DNIOBuffer(BufferProtocol obj, ByteBuffer storage, int index0, int count,
+ int stride) throws ArrayIndexOutOfBoundsException, NullPointerException {
super(storage, STRIDES, index0, count, stride);
+ this.obj = obj;
this.stride = stride; // Between items
if (count == 0) {
@@ -121,6 +124,7 @@
* <code>storage</code> array (unless <code>count=0</code>).
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage <code>ByteBuffer</code> wrapping exported data
* @param index0 index into storage of item[0]
* @param count number of items in the slice
@@ -130,9 +134,10 @@
* <code>stride</code> are inconsistent with <code>storage.length</code>
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public Strided1DNIOBuffer(int flags, ByteBuffer storage, int index0, int count, int stride)
- throws ArrayIndexOutOfBoundsException, NullPointerException, PyException {
- this(storage.duplicate(), index0, count, stride);
+ public Strided1DNIOBuffer(int flags, BufferProtocol obj, ByteBuffer storage, int index0,
+ int count, int stride) throws ArrayIndexOutOfBoundsException, NullPointerException,
+ PyException {
+ this(obj, storage.duplicate(), index0, count, stride);
checkRequestFlags(flags); // Check request is compatible with type
}
@@ -191,7 +196,7 @@
public SlicedView(PyBuffer root, int flags, ByteBuffer storage, int index0, int count,
int stride) throws PyException {
// Create a new slice on the buffer passed in (part of the root)
- super(flags, storage, index0, count, stride);
+ super(flags, root.getObj(), storage, index0, count, stride);
// Get a lease on the root PyBuffer (read-only)
this.root = root.getBuffer(FULL_RO);
}
diff --git a/src/org/python/core/buffer/Strided1DWritableBuffer.java b/src/org/python/core/buffer/Strided1DWritableBuffer.java
--- a/src/org/python/core/buffer/Strided1DWritableBuffer.java
+++ b/src/org/python/core/buffer/Strided1DWritableBuffer.java
@@ -1,5 +1,6 @@
package org.python.core.buffer;
+import org.python.core.BufferProtocol;
import org.python.core.PyBuffer;
import org.python.core.PyException;
@@ -25,6 +26,7 @@
* the sub-range the caller is allowed to use.
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage raw byte array containing exported data
* @param index0 index into storage of item[0]
* @param count number of items in the slice
@@ -34,9 +36,10 @@
* <code>stride</code> are inconsistent with <code>storage.length</code>
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public Strided1DWritableBuffer(int flags, byte[] storage, int index0, int count, int stride)
- throws ArrayIndexOutOfBoundsException, NullPointerException, PyException {
- super(storage, index0, count, stride);
+ public Strided1DWritableBuffer(int flags, BufferProtocol obj, byte[] storage, int index0,
+ int count, int stride) throws ArrayIndexOutOfBoundsException, NullPointerException,
+ PyException {
+ super(obj, storage, index0, count, stride);
addFeatureFlags(WRITABLE);
checkRequestFlags(flags); // Check request is compatible with type
}
@@ -107,7 +110,7 @@
public SlicedView(PyBuffer root, int flags, byte[] storage, int index0, int count,
int stride) throws PyException {
// Create a new on the buffer passed in (part of the root)
- super(flags, storage, index0, count, stride);
+ super(flags, root.getObj(), storage, index0, count, stride);
// Get a lease on the root PyBuffer (writable)
this.root = root.getBuffer(FULL);
}
diff --git a/src/org/python/core/buffer/ZeroByteBuffer.java b/src/org/python/core/buffer/ZeroByteBuffer.java
--- a/src/org/python/core/buffer/ZeroByteBuffer.java
+++ b/src/org/python/core/buffer/ZeroByteBuffer.java
@@ -1,5 +1,6 @@
package org.python.core.buffer;
+import org.python.core.BufferProtocol;
import org.python.core.PyBuffer;
import org.python.core.PyException;
@@ -25,12 +26,15 @@
* client code that may ask, if the results are customary for the exporting object.
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param readonly set true if not to be considered writable
* @param hasArray set true if to be considered as backed by an array
* @throws PyException (BufferError) when client expectations do not correspond with the type
*/
- public ZeroByteBuffer(int flags, boolean readonly, boolean hasArray) throws PyException {
+ public ZeroByteBuffer(int flags, BufferProtocol obj, boolean readonly, boolean hasArray)
+ throws PyException {
super(EMPTY, CONTIGUITY | (readonly ? 0 : WRITABLE), 0, 0, 1);
+ this.obj = obj;
if (!hasArray) {
// super() knows we have an array, but this truth is inconvenient here.
removeFeatureFlags(AS_ARRAY);
@@ -175,7 +179,7 @@
*/
public View(PyBuffer root, int flags) {
// Create a new ZeroByteBuffer on who-cares-what byte array
- super(flags, root.isReadonly(), root.hasArray());
+ super(flags, root.getObj(), root.isReadonly(), root.hasArray());
// But we still have to get a lease on the root PyBuffer
this.root = root.getBuffer(FULL_RO);
}
diff --git a/src/org/python/modules/_io/PyIOBase.java b/src/org/python/modules/_io/PyIOBase.java
--- a/src/org/python/modules/_io/PyIOBase.java
+++ b/src/org/python/modules/_io/PyIOBase.java
@@ -778,7 +778,7 @@
// None of the above: complain
throw tailoredTypeError("read-write buffer", obj);
}
- return new SimpleStringBuffer(PyBUF.SIMPLE, s);
+ return new SimpleStringBuffer(PyBUF.SIMPLE, null, s);
}
}
@@ -910,18 +910,17 @@
+ "fp is closed after the suite of the with statement is complete:\n" + "\n"
+ "with open('spam.txt', 'r') as fp:\n" + " fp.write('Spam and eggs!')\n";
-
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
- //closer cannot be null
+ // closer cannot be null
if (closer.sys != null) {
- int retVal = visit.visit(closer.sys, arg);
+ int retVal = visit.visit(closer.sys, arg);
if (retVal != 0) {
return retVal;
}
}
- //__dict__ cannot be null
+ // __dict__ cannot be null
return visit.visit(__dict__, arg);
}
diff --git a/tests/java/org/python/core/BaseBytesTest.java b/tests/java/org/python/core/BaseBytesTest.java
--- a/tests/java/org/python/core/BaseBytesTest.java
+++ b/tests/java/org/python/core/BaseBytesTest.java
@@ -203,6 +203,7 @@
*
* @see junit.framework.TestCase#setUp()
*/
+ @Override
protected void setUp() throws Exception {
super.setUp();
random = new Random(20120310L);
@@ -595,7 +596,7 @@
*/
public MyBytes(BufferProtocol value) {
super(TYPE);
- init((BufferProtocol)value.getBuffer(PyBUF.SIMPLE));
+ init(value.getBuffer(PyBUF.SIMPLE));
}
/**
@@ -787,7 +788,7 @@
@Override
public PyBuffer getBuffer(int flags) {
- return new SimpleBuffer(flags, store);
+ return new SimpleBuffer(flags, this, store);
}
}
@@ -824,7 +825,7 @@
return;
}
for (int i = 0; i < n; i++) {
- int c = 0xff & ((int)s[pos + i]);
+ int c = 0xff & (s[pos + i]);
if (c == 0) {
c = '.';
} else if (Character.isISOControl(c)) {
diff --git a/tests/java/org/python/core/PyBufferNIOTest.java b/tests/java/org/python/core/PyBufferNIOTest.java
--- a/tests/java/org/python/core/PyBufferNIOTest.java
+++ b/tests/java/org/python/core/PyBufferNIOTest.java
@@ -119,7 +119,7 @@
BaseBuffer pybuf = getExistingBuffer(flags);
if (pybuf == null) {
// No existing export we can re-use
- pybuf = new SimpleNIOBuffer(flags, storage) {
+ pybuf = new SimpleNIOBuffer(flags, this, storage) {
@Override
protected void releaseAction() {
@@ -200,7 +200,7 @@
BaseBuffer pybuf = getExistingBuffer(flags);
if (pybuf == null) {
// No existing export we can re-use
- pybuf = new RollYourOwnNIOBuffer(flags, storage);
+ pybuf = new RollYourOwnNIOBuffer(flags, this, storage);
// Hold a reference for possible re-use
export = new WeakReference<BaseBuffer>(pybuf);
}
@@ -227,26 +227,28 @@
* contiguous sequence of bytes from the position to the limit.
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage buffer exported (from the position to the limit)
*/
- public RollYourOwnNIOBuffer(int flags, ByteBuffer storage) {
- this(null /* =this */, flags, storage, storage.position(), storage.remaining(), 1);
+ public RollYourOwnNIOBuffer(int flags, BufferProtocol obj, ByteBuffer storage) {
+ this(flags, null /* =this */, obj, storage, storage.position(), storage.remaining(), 1);
}
/**
* Construct a slice of a one-dimensional byte buffer.
*
+ * @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param root on which release must be called when this is released
- * @param flags consumer requirements
* @param storage buffer containing exported data
* @param index0 index into storage of item[0]
* @param count number of items in the slice
* @param stride in between successive elements of the new PyBuffer
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public RollYourOwnNIOBuffer(PyBuffer root, int flags, ByteBuffer storage, int index0,
- int count, int stride) throws IndexOutOfBoundsException, NullPointerException,
- PyException {
+ public RollYourOwnNIOBuffer(int flags, PyBuffer root, BufferProtocol obj,
+ ByteBuffer storage, int index0, int count, int stride)
+ throws IndexOutOfBoundsException, NullPointerException, PyException {
// Client will need to navigate using shape and strides if this is a slice
super(FEATURES | ((index0 == 0 && stride == 1) ? 0 : STRIDES), //
index0, new int[] {count}, new int[] {stride});
@@ -265,8 +267,10 @@
// Get a lease on the root PyBuffer (read-only). Last in case a check above fails.
if (root == null) {
this.root = this;
+ this.obj = obj;
} else {
this.root = root.getBuffer(FULL_RO);
+ this.obj = root.getObj();
}
}
@@ -279,7 +283,7 @@
public PyBuffer getBufferSlice(int flags, int start, int count, int stride) {
int newStart = index0 + start * strides[0];
int newStride = strides[0] * stride;
- return new RollYourOwnNIOBuffer(root, flags, storage, newStart, count, newStride);
+ return new RollYourOwnNIOBuffer(flags, root, null, storage, newStart, count, newStride);
}
@Override
diff --git a/tests/java/org/python/core/PyBufferTest.java b/tests/java/org/python/core/PyBufferTest.java
--- a/tests/java/org/python/core/PyBufferTest.java
+++ b/tests/java/org/python/core/PyBufferTest.java
@@ -273,6 +273,13 @@
assertEquals("unexpected length", ref.length, view.getLen());
}
+ /** Test method for {@link org.python.core.PyBUF#getObj()}. */
+ @Test
+ public void testGetObj() {
+ announce("getObj");
+ assertEquals("unexpected exporting object", obj, view.getObj());
+ }
+
/** Test method for {@link org.python.core.PyBuffer#byteAt(int)}. */
@Test
public void testByteAt() {
@@ -1279,7 +1286,7 @@
@Override
public PyBuffer getBuffer(int flags) {
- return new SimpleBuffer(flags, storage);
+ return new SimpleBuffer(flags, this, storage);
}
}
@@ -1368,7 +1375,7 @@
BaseBuffer pybuf = getExistingBuffer(flags);
if (pybuf == null) {
// No existing export we can re-use
- pybuf = new SimpleStringBuffer(flags, storage);
+ pybuf = new SimpleStringBuffer(flags, this, storage);
// Hold a reference for possible re-use
export = new SoftReference<BaseBuffer>(pybuf);
}
@@ -1404,7 +1411,7 @@
BaseBuffer pybuf = getExistingBuffer(flags);
if (pybuf == null) {
// No existing export we can re-use
- pybuf = new SimpleWritableBuffer(flags, storage) {
+ pybuf = new SimpleWritableBuffer(flags, this, storage) {
@Override
protected void releaseAction() {
@@ -1435,7 +1442,7 @@
BaseBuffer pybuf = getExistingBuffer(flags);
if (pybuf == null) {
// No existing export we can re-use
- pybuf = new RollYourOwnArrayBuffer(flags, storage);
+ pybuf = new RollYourOwnArrayBuffer(flags, this, storage);
// Hold a reference for possible re-use
export = new WeakReference<BaseBuffer>(pybuf);
}
@@ -1461,26 +1468,28 @@
* Create a buffer view of the entire array.
*
* @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage byte array exported in its entirety
*/
- public RollYourOwnArrayBuffer(int flags, byte[] storage) {
- this(null /* =this */, flags, storage, 0, storage.length, 1);
+ public RollYourOwnArrayBuffer(int flags, BufferProtocol obj, byte[] storage) {
+ this(flags, null /* =this */, obj, storage, 0, storage.length, 1);
}
/**
* Construct a slice of a one-dimensional byte array.
*
+ * @param flags consumer requirements
* @param root on which release must be called when this is released
- * @param flags consumer requirements
+ * @param obj exporting object (or <code>null</code>)
* @param storage raw byte array containing exported data
* @param index0 index into storage of item[0]
* @param count number of items in the slice
* @param stride in between successive elements of the new PyBuffer
* @throws PyException (BufferError) when expectations do not correspond with the type
*/
- public RollYourOwnArrayBuffer(PyBuffer root, int flags, byte[] storage, int index0,
- int count, int stride) throws IndexOutOfBoundsException, NullPointerException,
- PyException {
+ public RollYourOwnArrayBuffer(int flags, PyBuffer root, BufferProtocol obj, byte[] storage,
+ int index0, int count, int stride) throws IndexOutOfBoundsException,
+ NullPointerException, PyException {
// Client will need to navigate using shape and strides if this is a slice
super(FEATURES | ((index0 == 0 && stride == 1) ? 0 : STRIDES), //
index0, new int[] {count}, new int[] {stride});
@@ -1498,8 +1507,10 @@
// Get a lease on the root PyBuffer (read-only). Last in case a check above fails.
if (root == null) {
this.root = this;
+ this.obj = obj;
} else {
this.root = root.getBuffer(FULL_RO);
+ this.obj = root.getObj();
}
}
@@ -1512,7 +1523,8 @@
public PyBuffer getBufferSlice(int flags, int start, int length, int stride) {
int newStart = index0 + start * strides[0];
int newStride = strides[0] * stride;
- return new RollYourOwnArrayBuffer(root, flags, storage, newStart, length, newStride);
+ return new RollYourOwnArrayBuffer(flags, root, null, storage, newStart, length,
+ newStride);
}
@Override
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list