More specifically...

The issue here is that there are multiple return values.  
gncOwnerCreatePaymentLotSecs() is *RETURNING* both a GNCLot* and a
Transaction*.  However, C doesn't allow you to do that, so the function
returns the GNCLot* and assigns the Transaction* to the Transaction**
argument as a second return value.

Your proposed wrapper here is wrong.

You can either write a wrapper that obtains the transaction and then
unrefs it (returning only the Lot), or you can write a wrapper that
obtains both values and returns the tuple (Lot, Txn) in Python -- assuming
Python, like Scheme, allows that.

Most likely this is why the function wasn't wrapped before -- due to the
complexities of the double return values.

-derek

On Tue, May 10, 2022 5:23 pm, Matteo Lasagni wrote:
> If I can find a good solution, yes, I will put it in a pull request.
>
> I have tried to encapsulate Transaction* in a list, but of course it
> doesn't work without touching swig definitions.
> I am now trying to create a specific typemap for handling the double
> pointer. I think this would be the cleanest solution.
>
> Alternatively, a quick and dirty workaround is to add a C wrapper in
> gncOwner.c that expects Transaction* and passes Transaction** to
> gncOwnerCreatePaymentLotSecs:
>
>
> GNCLot *
> gncOwnerCreatePaymentLotSecsPyHelper (const GncOwner *owner, Transaction
> *txn, Account *posted_acc, Account *xfer_acc, gnc_numeric amount,
> gnc_numeric exch, time64 date, const char *memo, const char *num)
> {
>     return gncOwnerCreatePaymentLotSecs(owner, &txn, posted_acc, xfer_acc,
> amount, exch, date, memo, num);
> }
>
>
> regards,
> Matteo
>
> On Tue, 10 May 2022 at 17:25, john <jra...@ceridwen.us> wrote:
>
>>
>>
>> On May 10, 2022, at 1:53 AM, Matteo Lasagni <laser...@gmail.com> wrote:
>>
>> Thank you, John!
>>
>> I fixed it by adding the following into base-typemaps.i:
>>
>> %typemap(in) GList * {
>>     $1 = NULL;
>>     /* Check if is a list */
>>     if (PyList_Check($input)) {
>>         int i;
>>         int size = PyList_Size($input);
>>         for (i = size-1; i >= 0; i--) {
>>             PyObject *o = PyList_GetItem($input, i);
>>             $1 = g_list_prepend($1, o);
>>         }
>>     } else {
>>         PyErr_SetString(PyExc_TypeError, "not a list");
>>         return NULL;
>>     }
>> }
>>
>> I had overlooked the swig definition in engine.i, where there is a
>> typemap
>> (in) for GList, but then it is cleared right afterwards...
>> I am not (yet) very familiar with swig :-)
>>
>> I have also noticed that CreatePaymentLotSecs does not work out of the
>> box, as it expects **Transaction while only *Transaction is type mapped.
>>
>> I will test these changes then I will figure out how to share them with
>> the developers.
>>
>>
>> Matteo
>>
>>
>> On Tue, 10 May 2022 at 02:32, John Ralls <jra...@ceridwen.us> wrote:
>>
>>>
>>>
>>> > On May 9, 2022, at 2:17 PM, Matteo Lasagni <laser...@gmail.com>
>>> wrote:
>>> >
>>> > Hi,
>>> > I am writing a python script to automatically associate a set of
>>> > invoices to a single transaction.
>>> > To this end, I am trying to use the function
>>> AutoApplyPaymentsWithLots
>>> > with no success:
>>> >
>>> >
>>> > lots = [lot1, lot2, lotn, ..]
>>> > owner.AutoApplyPaymentsWithLots(lots)
>>> >
>>> > This causes the following error:
>>> >
>>> > TypeError: in method 'gncOwnerAutoApplyPaymentsWithLots', argument 2
>>> of
>>> > type 'GList *'
>>> >
>>> > I have tried different solutions from passing different types of
>>> python
>>> > objects, to updating the swig typemap and also to modifying the
>>> > auto-generated gnucash_core.c...nothing worked out so far.
>>> > I could write an additional c-wrapper, but I am sure there is a more
>>> > general solution.
>>>
>>> The fundamental problem is that there's only a Python out typemap for
>>> GList, that is one that converts from a GList* to a python list.
>>> Lacking an
>>> in typemap the gncOwner.AutoApplyPaymentsWithLots python wrapper
>>> expects an
>>> already constructed and Swig-wrapped GList*.
>>>
>>> Regards,
>>> John Ralls
>>>
>>>
>>
>> Nice. Would you put that in a pull request?
>>
>> There are two typemap(in) GList* in engine.i, but they're both for Guile
>> (Scheme), not Python. 'scm' is the giveaway.
>>
>> If there's a way to implement an output pointer parameter in Python I
>> don't know about it. You can pass in a container object and put the
>> output
>> Transaction* in the container, but that's both a bit of a hack and
>> doesn't
>> have the same meaning as Transaction** nor is it very pythonic. Nor, for
>> that matter, is gncOwnerCreatePaymentLotSecs a very good design as it
>> mixes
>> responsibilities. Unfortunately there's a lot of that in GnuCash because
>> most of it is written with a very narrow focus, in this case providing
>> for
>> the payments dialog.
>>
>> Regards,
>> John Ralls
>>
>>
>
> --
>
> -------------
> Matteo Lasagni
>
>
> *"You can't connect the dots looking forward,you can only connect them
> looking backwards"* [Steve Jobs]
> _______________________________________________
> gnucash-devel mailing list
> gnucash-devel@gnucash.org
> https://lists.gnucash.org/mailman/listinfo/gnucash-devel
>


-- 
       Derek Atkins                 617-623-3745
       de...@ihtfp.com             www.ihtfp.com
       Computer and Internet Security Consultant

_______________________________________________
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to