Add endian keyword argument to type reads#144
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## add-copy #144 +/- ##
========================================
Coverage 0.00% 0.00%
========================================
Files 21 21
Lines 2500 2551 +51
========================================
- Misses 2500 2551 +51
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
15ab019 to
8a6b8b6
Compare
8a6b8b6 to
1cad01c
Compare
Merging this PR will degrade performance by 11.41%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing |
c8419f6 to
df8bbb9
Compare
|
I rebased on #140 and added the context manager. |
|
|
||
| def _read(cls, stream: BinaryIO, context: dict[str, Any] | None = None) -> Self: # type: ignore | ||
| def _read( | ||
| cls, stream: BinaryIO, *, context: dict[str, Any] | None = None, endian: Endianness | None = None, **kwargs |
There was a problem hiding this comment.
I vaguely remember our discussion about adding **kwargs for future proofing the API (or was it backwards compatibility?).
But I kinda forgot what the use case was. I'm also not sure if this is the best solution anymore, because using **kwargs can introduce mistyped keyword arguments, eg: if someone used endain='little' it would go unnoticed.
Please help me remember :)
There was a problem hiding this comment.
It was for future proofing, in case we want to add additional keyword arguments in the future, it would break custom type implementors. I do agree with your point, and on the one hand we've only added one new keyword argument in 8 years time. On the other, if we do want to add more, it'd probably have to be a major version bump each time. Unless you can think of another way.
I looked a little closer, but I wanted to keep my original message too. The kwargs is only present in the _read methods, which will only ever be used/implemented by (custom) type implementations. The "end user" of cstruct will always use the non-sunder-methods read(s), write, dumps, uint32(..., endian=). In fact, for the "call the type directly" method, this is already a risk. But due to how cstruct works, there's not really anything we can change in that. For all other "public" methods though, this is not a risk, because they do not use kwargs.
So, in short, the only time someone would be dealing with these kwargs is if they're implementing their own custom type. In which case, this would correctly act as "future proofing" it against any new keyword arguments.
Oh oops, you added it in the PR message:
anyway, my comment about the risks of using **kwargs still stand. In which case would it break backwards compatibility? |
f8fb6b1 to
fd1fe6d
Compare
|
Improved the docstrings and replied to your comment 😄. |
Partially solves #143, but I'd still like the context manager approach to be in there too. But that depends on #140.
Adds the ability to override the endianness on single type reads. So for example:
This should work on any type, including structs, unions and pointers.
Because the function signature for type reading and writing changes because of this, I also added a check when adding a custom type to ensure it's signature is correct. If it's not, it will either throw a (descriptive) error or issue a warning. I also intentionally added a
**kwargsto the function signature to allow for future expansion without breaking backwards compatibility again.I'm not 100% if the behavior of pointers is as expected. I implemented it so that:
.dereference(endian=).dumps()will fall back to the cstruct instance endianness, unless overridden