Working example of kvp acess in Python

John Ralls jralls at
Wed Nov 12 21:05:29 EST 2014

> On Nov 12, 2014, at 3:56 PM, Christoph Holtermann <c.holtermann at> wrote:
> Hello,
> for my part i answered some of the questions myself:
> Am 12.11.2014 um 18:46 schrieb Christoph Holtermann:
>> Hello,
>> so KVPs should be accessed by objects they belong to and not from the outside.
>> Some questions:
>> * Is it legitimate to have KVP representation in Python at all or is this low-level und
>> should remain to the c-api ?
> It is legitimate but use should be restricted. Maybe warning docs or putting them in a submodule
> called low_level.

In 2.6 and before KVP is part of the public API and is accessed directly from all over the program. If you're working with 2.6 you have no alternative to using KVP directly if you need access to some items stored there because the classes that the KVP is associated with have no code that manipulates those KVP items.

In master, KVP is a private implementation detail. The KVP accesses outside of src/engine have been assigned GObject Properties on their associated objects and should be accessed that way (except for one: I discovered a KVP access done in Scheme that had escaped my notice and which is still on the loose). Since the API is going to change rather a lot as we convert to C++ you probably want to ignore all of that and stick with the 2.6 API until we start the 2.7 releases.

>> * The information that I'm interested in is the company data for invoices. As far as
>> I' ve seen there is just KVP access to that.
>> * It seems to me that there should be an object Company that is structured similar
>> to Customer and has an assigned object Address identical to Customer.
>> * When only the object should be able to access KVP, who is this object for the
>> company address ? At the moment it's book, I guess.
>> * I could create a python object Company and add getter functions that access the
>> KVPs. But it seems better to me to not introduce objects in python that do not exist
>> in c.
>> * On the other hand it can still be changed afterwards if an object is introduced in
>> c.
> I decide to create an object Company.
> This I can easily be put to jinja in my invoice_export script.
> I'm quite happy to be able to submit all the information by this simple call:
> output = template.render(invoice=invoice, locale=locale, company=Company(book))
> I posted a pull request for the jinja2 approach. The inclusion of access to the Company
> data remains head of my development fork:
> Maybe you can have a look and it and we can come to an agreement if the Company
> and KVP approach is adequate or how it can be improved.
> Further steps would be a closer integration into the GUI.

To date our policy on the Python bindings is that they're for users to query the GC database for their own use. We're don't accept Python extensions of GnuCash into GnuCash itself and have no intention or interest in adding Python interpreters to the Mac and Windows AIO bundles. I don't see any reason to change that policy. I haven't yet looked at your pull request, but if it conflicts with that policy you can do me a favor and withdraw it.

My intention for KVP is to make it a backend implementation detail for storage only and completely invisible to the rest of the program. There are quite a few chunks of KVP that don't fit very well with the objects they're currently associated with. I expect that in the course of the C++ rewrite we'll be creating new classes to deal with them. Company data is one of those, the import account matching data is another, and there are more that don't come immediately to mind.

John Ralls

More information about the gnucash-devel mailing list