-
Notifications
You must be signed in to change notification settings - Fork 295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid throw/catch exceptions when requesting optional buffer through IBufferProtocol
#1902
Conversation
…`IBufferProtocol`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throwOnError
feels like kind of an odd pattern for a public API, but I couldn't think of anything much better.
An alternate pattern could be:
[return: NotNullIfNotNull(nameof(error))]
public IPythonBuffer? TryGetBuffer(BufferFlags flags, out string? error);
and then you could use it like this:
var buffer = TryGetBuffer(BufferFlags.Simple, out string? error) ?? throw PythonOps.BufferError(error);
src/core/IronPython/Runtime/Bytes.cs
Outdated
IPythonBuffer? IBufferProtocol.GetBuffer(BufferFlags flags, bool throwOnError) { | ||
if (flags.HasFlag(BufferFlags.Writable)) { | ||
if (throwOnError) { | ||
throw PythonOps.TypeError("bytes object is not writable"); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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…
Interesting, but frankly, this pattern looks to me even more unusual to as the one I proposed. Also, my intention was to put as little burden as possible on the implementers of the interface. So Also as I understand |
BTW, the proposed pattern is not so unusual, I knew I've seen it somewhere before: public virtual Type? GetType (string name, bool throwOnError); Anyway, I'm checking in some changes to the |
Well, the Anyway, I guess the code contract can be whatever we make it and I don't have better names/patterns to propose (
Ugh yeah, I need more sleep. 😄 |
It turns out that
GetBufferNoThrow
is quite popular. However, it entailed atry
/catch
ofBufferException
, which incurs a performance penalty. In CPython, it turns out it is fairly common to try to get a buffer that is not supported , and then fall back on some more supported versions, since the error is inexpensive to return. However, it requires checking every return value, which is not convenient to the users of the interface. Besides, it is the provider, not the user, that can describe the error best.This PR keeps the current of the usage interface the same, while keeping the complexity of implementing
IBufferProtocol
at a similar level, and avoiding the try/catch of the exception for unsupported calls.