Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/core/IronPython.Modules/_ctypes/CData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public void Dispose() {

private int _numExports;

IPythonBuffer IBufferProtocol.GetBuffer(BufferFlags flags) {
IPythonBuffer IBufferProtocol.GetBuffer(BufferFlags flags, bool throwOnError) {
if (_disposed) throw new ObjectDisposedException(GetType().Name);
_ = MemHolder; // check if fully initialized
Interlocked.Increment(ref _numExports);
Expand Down
2 changes: 1 addition & 1 deletion src/core/IronPython.Modules/array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ bool ICollection<object>.Remove(object item) {

#region IBufferProtocol Members

IPythonBuffer IBufferProtocol.GetBuffer(BufferFlags flags) {
IPythonBuffer IBufferProtocol.GetBuffer(BufferFlags flags, bool throwOnError) {
return _data.GetBuffer(this, _typeCode.ToString(), flags);
}

Expand Down
11 changes: 7 additions & 4 deletions src/core/IronPython.Modules/mmap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1314,10 +1314,13 @@ void IWeakReferenceable.SetFinalizer(WeakRefTracker value) {

#endregion

public IPythonBuffer GetBuffer(BufferFlags flags = BufferFlags.Simple) {
if (flags.HasFlag(BufferFlags.Writable) && IsReadOnly)
throw PythonOps.BufferError("Object is not writable.");

public IPythonBuffer? GetBuffer(BufferFlags flags, bool throwOnError) {
if (flags.HasFlag(BufferFlags.Writable) && IsReadOnly) {
if (throwOnError) {
throw PythonOps.BufferError("Object is not writable.");
}
return null;
}
return new MmapBuffer(this, flags);
}

Expand Down
7 changes: 5 additions & 2 deletions src/core/IronPython/Runtime/BufferProtocol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace IronPython.Runtime {
/// Equivalent functionality of CPython's <a href="https://docs.python.org/3/c-api/buffer.html">Buffer Protocol</a>.
/// </summary>
public interface IBufferProtocol {
IPythonBuffer GetBuffer(BufferFlags flags = BufferFlags.Simple);
IPythonBuffer? GetBuffer(BufferFlags flags, bool throwOnError);
}

/// <summary>
Expand Down Expand Up @@ -120,9 +120,12 @@ public enum BufferFlags {
}

internal static class BufferProtocolExtensions {
internal static IPythonBuffer GetBuffer(this IBufferProtocol bufferProtocol, BufferFlags flags = BufferFlags.Simple)
=> bufferProtocol.GetBuffer(flags, throwOnError: true) ?? throw new BufferException("Buffer type not supported");

internal static IPythonBuffer? GetBufferNoThrow(this IBufferProtocol bufferProtocol, BufferFlags flags = BufferFlags.Simple) {
try {
return bufferProtocol.GetBuffer(flags);
return bufferProtocol.GetBuffer(flags, throwOnError: false);
} catch (BufferException) {
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/IronPython/Runtime/ByteArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1584,7 +1584,7 @@ private bool Equals(ReadOnlySpan<byte> other) {

#region IBufferProtocol Members

IPythonBuffer IBufferProtocol.GetBuffer(BufferFlags flags) {
IPythonBuffer IBufferProtocol.GetBuffer(BufferFlags flags, bool throwOnError) {
return _bytes.GetBuffer(this, "B", flags);
}

Expand Down
11 changes: 7 additions & 4 deletions src/core/IronPython/Runtime/Bytes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1241,10 +1241,13 @@ Expression IExpressionSerializable.CreateExpression() {

#region IBufferProtocol Support

IPythonBuffer IBufferProtocol.GetBuffer(BufferFlags flags) {
if (flags.HasFlag(BufferFlags.Writable))
throw PythonOps.BufferError("Object is not writable.");

IPythonBuffer? IBufferProtocol.GetBuffer(BufferFlags flags, bool throwOnError) {
if (flags.HasFlag(BufferFlags.Writable)) {
if (throwOnError) {
throw PythonOps.TypeError("bytes object is not writable");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a TypeError on this one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unintentional. VS Code trying to be helpful…

}
return null;
}
return new BytesView(this, flags);
}

Expand Down
7 changes: 5 additions & 2 deletions src/core/IronPython/Runtime/ConversionWrappers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -436,13 +436,16 @@ public MemoryBufferProtocolWrapper(Memory<byte> memory) {
_memory = memory;
}

public IPythonBuffer GetBuffer(BufferFlags flags) {
public IPythonBuffer? GetBuffer(BufferFlags flags, bool throwOnError) {
if (_memory.HasValue) {
return new MemoryBufferWrapper(_memory.Value, flags);
}

if (flags.HasFlag(BufferFlags.Writable)) {
throw Operations.PythonOps.BufferError("ReadOnlyMemory is not writable.");
if (throwOnError) {
throw Operations.PythonOps.BufferError("ReadOnlyMemory is not writable.");
}
return null;
}

return new MemoryBufferWrapper(_rom, flags);
Expand Down
23 changes: 15 additions & 8 deletions src/core/IronPython/Runtime/MemoryView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -963,32 +963,39 @@ void IWeakReferenceable.SetFinalizer(WeakRefTracker value) {

#region IBufferProtocol Members

IPythonBuffer IBufferProtocol.GetBuffer(BufferFlags flags) {
IPythonBuffer? IBufferProtocol.GetBuffer(BufferFlags flags, bool throwOnError) {
CheckBuffer();

if (flags.HasFlag(BufferFlags.Writable) && _isReadOnly)
throw PythonOps.BufferError("memoryview: underlying buffer is not writable");
return ReportError("memoryview: underlying buffer is not writable");

if (flags.HasFlag(BufferFlags.CContiguous) && !_isCContig)
throw PythonOps.BufferError("memoryview: underlying buffer is not C-contiguous");
return ReportError("memoryview: underlying buffer is not C-contiguous");

if (flags.HasFlag(BufferFlags.FContiguous) && !_isFContig)
throw PythonOps.BufferError("memoryview: underlying buffer is not Fortran contiguous");
return ReportError("memoryview: underlying buffer is not Fortran contiguous");

if (flags.HasFlag(BufferFlags.AnyContiguous) && !_isCContig && !_isFContig)
throw PythonOps.BufferError("memoryview: underlying buffer is not contiguous");
return ReportError("memoryview: underlying buffer is not contiguous");

// TODO: Support for suboffsets
//if (!flags.HasFlag(!BufferFlags.Indirect) && _suboffsets != null)
// throw PythonOps.BufferError("memoryview: underlying buffer requires suboffsets");
// return ReportError("memoryview: underlying buffer requires suboffsets");

if (!flags.HasFlag(BufferFlags.Strides) && !_isCContig)
throw PythonOps.BufferError("memoryview: underlying buffer is not C-contiguous");
return ReportError("memoryview: underlying buffer is not C-contiguous");

if (!flags.HasFlag(BufferFlags.ND) && flags.HasFlag(BufferFlags.Format))
throw PythonOps.BufferError("memoryview: cannot cast to unsigned bytes if the format flag is present");
return ReportError("memoryview: cannot cast to unsigned bytes if the format flag is present");

return new MemoryView(this, flags);

IPythonBuffer? ReportError(string msg) {
if (throwOnError) {
throw PythonOps.BufferError(msg);
}
return null;
}
}

#endregion
Expand Down