Uncaught critical error in the python bindings without apparent cause

John Ralls jralls at ceridwen.us
Tue Apr 10 17:36:06 EDT 2012

On Apr 10, 2012, at 3:51 PM, mail at janno-kaiser.de wrote:

> Hi,
> I've run into an error using the python bindings:
> This is the code (changed a bit to make it easier to read):
> c = book.CustomerLookupByID(customerid)
> assert( isinstance(c, Customer) )
> CUR = c.GetCurrency()
> assert( isinstance(CUR, GncCommodity) )
> invoice = Invoice(
>             book=book,
>             id=next_invoice_id,
>             currency=CUR,
>             owner=c
>             )
> It goes through without throwing an exception but produces the following
> output:
> * 19:41:21  CRIT <gnc.backend.sql> gnc_sql_save_commodity: assertion
> `pCommodity != NULL' failed
> * 19:41:21  WARN <gnc.backend.sql> [add_gvalue_owner_to_slist()] Invalid
> owner type: 0
> I used pdb to investigate this:
> - CUR is identical to book.get_table().lookup('CURRENCY', 'EUR')
> - c is a customer created manually using the gnucash GUI and all it's
> properties appear to be correct.
> - next_invoice_id is "W000083".
> I've stepped through the code. The first line ("CRIT") of the output
> happens here:
> /usr/lib/python2.7/dist-packages/gnucash/gnucash_core_c.py (3379)
> gncInvoiceSetID()
> -> return _gnucash_core_c.gncInvoiceSetID(*args)
> which is the result of this function call:
>> /usr/lib/python2.7/dist-packages/gnucash/gnucash_business.py (178)
> __init__()
> -> self.SetID(id)
> The "WARN" output is caused by this:
>> /usr/lib/python2.7/dist-packages/gnucash/gnucash_core_c.py (3407)
> gncInvoiceSetCurrency()
> -> return _gnucash_core_c.gncInvoiceSetCurrency(*args)
> which is the result of a simple SetCurrency in Invoice.__init__, one
> line after SetID.
> I'm very confused. How is the ID related to pCommodity and how is the
> currency related to the owner type? Since I've stepped through every
> function call I'm certain that the output happens at the locations I
> mentioned but it just doesn't make any sense to me.
> My gnucash version:
> GnuCash 2.4.10
> Built 2012-03-05 from r21973
> I don't know how to find the source of this problem. I'd appreciate any
> input.

The source is in the source, so to speak: The C sources, for which the python bindings are only a thin wrapper.

In particular, the first error comes from trying to save a NULL commodity pointer to the database. You'll find the actual assertion at src/backend/sql/gnc-commodity-sql.c line 251. The second is from trying to save an incompletely constructed Owner (parent class of Customer, Vendor, and Employee) at src/backend/sql/gnc-owner-sql.c line 263.

Most property setters in Gnucash are wrapped with beginEdit/commitEdit, so you can get backend errors like this if you set a property on an incompletely-constructed object. Object construction in Gnucash is at present pretty strange. In C you'd do something like
	gncInvoice *invoice = xaccMallocInvoice (book);
/* Call gncInvoiceBeginEdit to raise the editlevel and forestall commits until we're done */
	gncInvoiceBeginEdit (invoice);
/* Finish constructing invoice, then commit */
	gncInvoiceCommitEdit (invoice);

I don't know if that works in the python bindings. It's certainly not "pythonic".

John Ralls

More information about the gnucash-devel mailing list