eliben / pyelftools

Parsing ELF and DWARF in Python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Reading streams within constructors, design decision or noone cared?

mefistotelis opened this issue · comments

The tool reads from streams within __init__ of many objects. This means using copy.copy() on them is not only not working, but also hard to implement - as it requires refactoring the constructors.

Is there a reason for having stream reads in constructors? Shouldn't parsing be done in some kind of parse() method?

(I'm rebasing by clone with ELF write support, so I'll be patching that out, somehow)

EDIT: looks like the copy is really super easy to implement, because Python:

+    def __copy__(self):
+        cls = self.__class__
+        newone = cls.__new__(cls)
+        newone.__dict__.update(self.__dict__)
+        newone.header = self.header.copy()
+        return newone

But it would be still interesting to get some feedback on the parsing within constructor.

I'm not exactly sure what you're trying to accomplish, but why would we have a parse method when none is needed? It's just making using the classes more verbose. Right now you create an ELFFile, say, and you can immediately start accessing its data. What benefit is there in a parse method in the middle?

I'm not exactly sure what you're trying to accomplish

The big picture is, I made ELF modify/write support. This means I had to provide another source of data for all the sections - not only the stream, but also some data_updated buffer. But the current approach - having stream reads in __init__ - made it harder, or at least quite convoluted, to adjust everything after the data of a section gets replaced.

Right now you create an ELFFile, say, and you can immediately start accessing its data.

The parse() could be called soon after, or even just after the constructor. So the user wouldn't have to do anything more before accessing ELFFile. It would add this one call to object creation - so yes more verbose. But it would also make exception support easier to read - ie.

obj = _make_section()
try
    obj.parse()
except Exception as e:
    // parsing specific section type failed, use generic section instead
    obj = Section()
    obj.parse()

Thanks for the details. This is a very major API change that - realistically - won't happen at this stage of the project. It sounds like you have some workaround for your specific needs, though.

This is a very major API change that - realistically - won't happen at this stage of the project

That basically equals to "pyelftools will never support writing". I would be careful with such statements.
APIs do change over time.

I do have workarounds, and my fork is working - based on it, I made a tool which wraps plain ARM binary with ELF header:
https://github.com/o-gs/dji-firmware-tools/blob/master/arm_bin2elf.py

I guess what I'd like to ask for is - don't make design decisions which lead to write support being harder to implement, either by API or by internals relying on one data source. Mind the writing.