-
Notifications
You must be signed in to change notification settings - Fork 838
Added SWIG type translator for C functions that take GList* arguments #2066
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: stable
Are you sure you want to change the base?
Conversation
The test failures aren't your fault, please rebase on current stable. These type maps don't belong in base-typemaps.i You can move them to bindings/engine.i and guard them with |
6e0a5f1
to
8d0ea5a
Compare
@jralls , I have moved it to |
The long line of tests on every list member is going to be pretty expensive for the types at the end of the There's no point in casting the pointer when calling It's good that you're using Adding tests that exercise some of the function bindings that motivate this PR to make sure that it all works would be wise. |
@jralls , your point about untyped GLists raises a hairier issue--we can't actually verify in the typemap for GList that every object in this list is of the type that the function wants. If you tried to pass a Python list of GncInvoice objects to something expecting a GList of GncLot objects, it would pass them through, then try to cast the GncInvoice structures in C into GncLots and get garbage or a buffer overrun. Is this just something we're willing to accept because all these functions already take untyped GLists, or should we try to come up with some way of having the bindings check? Conceivably could make a Python class for LotList, AccountList, etc, and make those classes enforce that you can only add objects of a certain type. Would still have to have some large changes in the C or SWIG to be able to know what kind of GList a function actually wants. |
Hairy indeed. I was refreshing my memory about typemaps this morning and found that typemaps see through typedefs so
and
are equivalent because all of the others are typedefs of GList. But with separate typemaps [SWIG looks for the explicit type[]https://www.swig.org/Doc4.0/SWIGDocumentation.html#Typemaps_nn17) before checking typedefs. It's probably not worth the effort to type-check the untypedeffed GList* arguments. If you really think it worthwhile you could write a typemap for each of the contained types and then declare the functions that use it, repeating for each type. |
@jralls , I am unable to find a way to do this with just
I have confirmed in a debugger that the PyObject_GetAttrString function does return a SwigPyObject when you get "instance". And I have confirmed that |
@featherfeet You can find the code for Looks like a GNCLot* in the debugger isn't necessarily conclusive. If you tell the debugger |
d3c6a39
to
42b6b8c
Compare
@jralls , based on the file you referenced, I found how to get the type directly from SWIG so we don't have the long string of type-checks. This still has the issue of letting you pass a GList of the wrong type of objects, but that's not really fixable without changing lots of things that take generic GList arguments. Do I need to write a
Also, where would I start with regards to writing a test case for a Python binding function? |
42b6b8c
to
760584c
Compare
Indeed. I don't think there's a good way to type-check GObjects from Python.
Correct on both counts. The best you can do is to expose a free function so that GLists can be freed from Python. |
The python bindings test directory has examples, though many of them are more integration than unit tests. For unit testing the sort of test you wrote for #2074 is generally sufficient: It's not up to bindings to ensure that the wrapped function does what it's supposed to, just to make sure that the inputs and outputs are what they're supposed to be. |
… to autoconvert Python lists of high-level Gnucash core objects. Fixes issue with Customer.ApplyPayment in Python (gncOwnerApplyPaymentSecs in C).
760584c
to
e31f138
Compare
@jralls , I have added a unit test that uses the payment function and checks that it zeroes out Accounts Receivable. The %freefunc directive appears to not be available from Python, and I can't directly write a free function that you call manually from Python because the GList* is on the C side. |
@featherfeet I don't know how you got from
to Another option might be to use BTW, I've fixed the warnings that caused the Arch Linux CI failure, rebase to get it to pass. |
return NULL; | ||
} | ||
|
||
// Reverse list to preserve original order. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed. The prepends start from the end of the list. Plus, the g_list_reverse would typically be outside rather than inside the for loop.
Fixes issues with Python SWIG bindings for functions that take GList arguments, see this thread.