libgit2 / pygit2

Python bindings for libgit2
https://www.pygit2.org/
Other
1.61k stars 385 forks source link

Custom Python ODB backends - write() support #1057

Open rokel opened 3 years ago

rokel commented 3 years ago

Is there any support for implementing write() for custom python ODB backends?

I noticed it wasn't in the docs, but tried implementing it like so:

class MyOdbBackend(pygit2.OdbBackend):

    # snip - other OdbBackend methods

   def write(self, oid, data, length, type):
        print(f"writing {oid} {length} type {type}")
        return True

repo = pygit2.Repository()
odb = pygit2.Odb()
odb.add_backend(MyOdbBackend(), 1)
repo.set_odb(odb)

test_blob_id = repo.create_blob(b"hello world\n")
print(repo[test_blob_id].data)

But I get a _pygit2.GitError: TLS backend doesn't support certificate locations on calling repo.create_blob(). The built-in backends seem to work fine.

ttylta commented 3 years ago

Any word on this?

techtonik commented 3 years ago

This repo needs an issue template to report pygit2 and libgit2 versions.

justinnuwin commented 3 years ago

There doesn't seem to be any error checking after the Python methods are called from OdbBackend which causes that error to be raised. I got the custom backend working with v1.6.1 without errors. Although with the updated TODO in 64e9acd, I'm not sure what @jdavid 's plans to for this existing API may be.

import pygit2

class CustomOdbBackend(pygit2.OdbBackend):
    def __init__(self):
        super().__init__()
        self.objects = {}

    def write_cb(self, oid, data, otype):
        print(f'write {type(oid)}:{oid} {data} {otype}')
        oid = str(oid)
        self.objects[oid] = {'data': data, 'type': otype}
        return True

    def read_cb(self, oid):
        print(f'read {type(oid)}:{oid}')
        oid = str(oid)
        return self.objects[oid]['type'], self.objects[oid]['data']

    def read_prefix_cb(self, oid: str):
        print(f'read_prefix {type(oid)}:{oid}')
        obj = self.objects[oid]
        return obj['type'], obj['data'], oid

    def read_header_cb(self, oid):
        print(f'read_header {type(oid)}:{oid}')
        obj = self.objects[oid]
        return obj['type'], len(obj['data'])

    def exists_cb(self, oid):
        print(f'exists {type(oid)}:{oid}')
        oid = str(oid)
        return oid in self.objects

    def exists_prefix_cb(self, oid):
        print(f'exists_prefix {type(oid)}:{oid}')
        return oid

    def refresh_cb(self):
        print(f'refresh')
        return

repo = pygit2.Repository()
odb = pygit2.Odb()
odb.add_backend(CustomOdbBackend(), 1)
repo.set_odb(odb)

print('Writing blob')
test_blob_id = repo.create_blob(b'Hello, World!\n')
print(f'Got hash {type(test_blob_id)}:{test_blob_id}')
print('=====')
print('Read-back', repo[test_blob_id].data)