Implement Bytes.__new__#943
Conversation
slozier
left a comment
There was a problem hiding this comment.
Seems generally good.
Not that I necessarily think this PR needs to be amended for these cases (since we weren't supporting them before), but we're missing the "always call __bytes__" whenever we hit specialized __new__ overloads:
class BytesSubclass(bytes):
def __bytes__(self):
return BytesSubclass(b"x")
x = bytes(BytesSubclass(b"y"))
assert type(x) is BytesSubclass and x == b"x"
class Test(str):
def __bytes__(self):
return b"bytes"
assert Test("str") == b"bytes"| if (!isLittle && byteorder != "big") throw PythonOps.ValueError("byteorder must be either 'little' or 'big'"); | ||
|
|
||
| return FromBytes(new Bytes(context, bytes), isLittle, signed); | ||
| return FromBytes((Bytes)Bytes.__new__(context, TypeCache.Bytes, bytes), isLittle, signed); |
There was a problem hiding this comment.
Calling __new__ from C# seems a bit icky. I wonder if we should have a Bytes Bytes.FromObject(object) helper instead.
There was a problem hiding this comment.
Yeah, I wasn't fond of it either. Will try to factor it out.
|
Oh, I forgot about
I assume you meant assert bytes(Test("str")) == b"bytes"This one throws on CPython 3.4 (which is the one I use for testing for IronPython 3) but now I see it works under CPython 3.5. It looks to me like an ommision in CPython 3.4 that got rectified in the next release so I am going to implement the later behaviour. |
slozier
left a comment
There was a problem hiding this comment.
Looks good to me assuming the tests pass. Just a minor suggestion.
| public static object __new__(CodeContext context, [NotNull] PythonType cls, [NotNull] IBufferProtocol source) { | ||
| if (cls == TypeCache.Bytes) { | ||
| return new Bytes(source); | ||
| if (TryInvokeBytesOperator(context, source, out Bytes? res)) { |
There was a problem hiding this comment.
Maybe an if (source.GetType() == typeof(Bytes)) return source;? Could use the same optimization in FromObject.
There was a problem hiding this comment.
How about a separate overload?
There was a problem hiding this comment.
In 05ceb50 I added an overload for the C# constructor with a Bytes parameter as a fast track. I was also thinking about an overload for the Python __new__ constructor, but this would not work: it would catch also the subclasses and those have to be tried with __bytes__.
This is primarily to support the following case (from stdlib tests):
Also an opportunity to clean up constructor overloads in
Bytes.