Description
Hey,
like a year ago or more there were some design changes in the way iterations are handled in libgit2. Now there exist two ways of getting all the entries of a container for example like reflogs, trees or references. For reflog you do it the old for-loop style with finding out the size of the container and then accessing the entry itself with an index. For notes in contrast you have to provide callback function and libgit2 iterates through the container and calls for each iteration step the provided callback. In the following some examples:
*_entrycount
/ *_entry_by_index
- git_reflog_entry_byindex / git_reflog_entrycount
- git_tree_entry_byindex / git_tree_entrycount
*_foreach
- git_reference_foreach
- git_note_foreach
- git_diff_foreach
- ...
In pygit2 the latter iteration handling is gettig us into trouble. As some may know in python, in comparison for example to ruby, you do not have blocks. For iterating you use for-loops or list comprehensions. So generally you do not use anonymous functions (callbacks) for each iteration step. Therefor it is really hard to provide a binding for these new _foreach
-functions efficiently. We have to iterate through the whole list, make a PyList-object out of it and give it back to python. So if a user only wants the first two note entries this is a huge disadvantage (it is not lazy). However for _entrycount
/_entry_by_index
we can build a generator object because here we only have to provide a next()
method. This is not possible for these foreach-iterators because we can not jump out of our called callback to our caller function. For an implemenation example you can have a look at RefLogIter_iternext()
in src/reflog.c and Diff_changes__get__
in src/diff.c.
So the resulting question is: Is there any possibility to use these foreach-iterators in an old fashioned way? (Even with setjmp.h it seems not possible - not that I would want to abuse them for this...) Or is it possible to provide as well _entrycount
-/_entry_by_index
- besides _foreach
-functions?
I think several bindings could run into this issue (except they are callback based or have yield in the binding level layer)
Greeting
Nico