the scope of local variable in the function is not kept until context manager is alive. causing SIGSEGV.
Pull up local variables in function into an instance field as shown in below fixed the problem.
It means that another code in read.py has problem like this too.
@contextmanager
def custom_reader(self,
read_func, format_name='all', filter_name='all',
open_func=None, seek_func=None, close_func=None,
block_size=page_size, archive_read_class=libarchive.read.ArchiveRead, passphrase=None,
):
"""Read an archive using a custom function.
"""
from libarchive import ffi
self.open_cb = OPEN_CALLBACK(open_func) if open_func else NO_OPEN_CB
self.read_cb = READ_CALLBACK(read_func)
self.close_cb = CLOSE_CALLBACK(close_func) if close_func else NO_CLOSE_CB
self.seek_cb = SEEK_CALLBACK(seek_func)
with new_archive_read(format_name, filter_name, passphrase) as self.archive_p:
if seek_func:
ffi.read_set_seek_callback(self.archive_p, self.seek_cb)
ffi.read_open(self.archive_p, None, self.open_cb, self.read_cb, self.close_cb)
yield archive_read_class(self.archive_p)
class Holder(object):
pass
I think you got confused. The premature garbage collection of the seek callback was fixed in #116, but it hadn't been released yet. It's in version 3.2 now.
https://github.com/Changaco/python-libarchive-c/blob/8256dba743dc4f777ab31ae96222af548fb78957/libarchive/read.py#L58-L73
the scope of local variable in the function is not kept until context manager is alive. causing SIGSEGV. Pull up local variables in function into an instance field as shown in below fixed the problem. It means that another code in read.py has problem like this too.
@contextmanager
def custom_reader(self, read_func, format_name='all', filter_name='all', open_func=None, seek_func=None, close_func=None, block_size=page_size, archive_read_class=libarchive.read.ArchiveRead, passphrase=None, ): """Read an archive using a custom function. """ from libarchive import ffi self.open_cb = OPEN_CALLBACK(open_func) if open_func else NO_OPEN_CB self.read_cb = READ_CALLBACK(read_func) self.close_cb = CLOSE_CALLBACK(close_func) if close_func else NO_CLOSE_CB self.seek_cb = SEEK_CALLBACK(seek_func) with new_archive_read(format_name, filter_name, passphrase) as self.archive_p: if seek_func: ffi.read_set_seek_callback(self.archive_p, self.seek_cb) ffi.read_open(self.archive_p, None, self.open_cb, self.read_cb, self.close_cb) yield archive_read_class(self.archive_p) class Holder(object): pass