-
Notifications
You must be signed in to change notification settings - Fork 3
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
WIP: Dataclass #31
WIP: Dataclass #31
Conversation
@philippeitis are you interrested in reviewing this? |
I don't mind |
Is there any reason you don't implement the data class like so:
Having to do |
Yeah, it's either that way or removing the need to inherit from BinmapDataclass I think. Having the decorator could have a value since it clearly shows in the code that it is a dataclass. |
Missed empty line
I don't think it matters if the code is a dataclass or not, since the code still behaves the same way. This is really just an implementation detail which the user should not have to think about - I'd stick with extending the class, since it's more informative about the methods and behaviours you'll inherit, as opposed to a decorator. And yes, it's only needed when declaring the class - my suggestion of moving the logic to the init_subclass works just fine, since we're directly modifying the class object. |
- Add shortnames for types that matches tha names in struct.
if value in obj._enums[self.name]: | ||
obj.__dict__[f"_{self.name}"] = value | ||
datafieldsmap = {f.name: f for f in dataclasses.fields(obj)} | ||
if type(value) is str: |
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.
if isinstance(value, str):
This allows subtypes which may be relevant here.
obj.__dict__[f"_{self.name}"] = value | ||
datafieldsmap = {f.name: f for f in dataclasses.fields(obj)} | ||
if type(value) is str: | ||
datafieldsmap[self.name].metadata["enum"][value] |
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 is this a dictionary access? I'd leave a comment explaining this if its supposed to be here.
binmap/__init__.py
Outdated
if self.name in obj.__dict__: | ||
raise AttributeError(f"{self.name} is a constant") | ||
else: | ||
obj.__dict__.update({self.name: value}) |
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 not set these values with obj.__dict__[self.name] = value
?
binmap/__init__.py
Outdated
obj.__dict__.update({self.name: value}) | ||
|
||
|
||
char = NewType("char", int) |
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.
Typically, you want to put constants at the top of the file, with variable names in all caps to help identify them - eg: CHAR = NewType("char", int)
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.
binmap/__init__.py
Outdated
setattr(cls, field_.name, _base(name=field_.name)) | ||
if type_hints[field_.name] is pad: | ||
_type = field_.default * _type | ||
if ( |
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.
I would do type_hints[field_.name] in (string, pascalstring, str)
here.
binmap/__init__.py
Outdated
class BinmapDataclass(ABC): | ||
_byteorder = "" | ||
_formatstring = "" | ||
__binarydata: dataclasses.InitVar[bytes] = b"" |
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 do we have __binarydata
and _binarydata
?
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.
I changed that in later (already pushed) changes.
binmap/__init__.py
Outdated
datafields = [ | ||
field for field in self._datafields if not field.startswith("_pad") | ||
f.name for f in dataclasses.fields(self) if not (type_hints[f.name] is pad) |
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.
type_hints[f.name] is not pad
if _binarydata != b"": | ||
self._unpacker(_binarydata) | ||
# Kludgy hack to keep order | ||
for f in dataclasses.fields(self): |
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.
Should we store our fields like so self._fields = dataclasses.fields(self)
?
def __post_init__(self, _binarydata: bytes): | ||
if _binarydata != b"": | ||
self._unpacker(_binarydata) | ||
# Kludgy hack to keep order |
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.
Should we maintain order through an internal class variable to allow the user to set the order themselves (for instance, _order
)? This would also help avoid the self.__dict__.update(...)
strangeness.
else: | ||
self._binarydata = b"" | ||
if "constant" in f.metadata: | ||
self.__dict__.update({f.name: f.default}) |
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.
Again, this should be commented, but preferably, we should not be relying on this to maintain order.
Some of my comments may be off by a line or two - turns out the comments weren't submitted when I thought they were - hopefully they should still be close enough. |
No need for decorator now.
Addressed some of the comments and reworked some initializations. |
Merging it now, it could be easier to work with after that. |
Would solve #23
Needs: