qof_query_search_for stores the pointer of the QofIdType argument without copying the string. This causes queries using the python 3 bindings to fail because the QofIdType argument pointer is invalid by the time the query is run as the QofidType argument string is only valid for the lifetime of the wrapper function for qof_query_search_for.
This API is working as specified. The QofIdType is a static constant, and this API specifies that it store the pointer thereto. The Python binding needs to work with the C API specification, not the other way around.
Not only is the API not specified or documented anywhere, it's utterly non-bindable. There's no way to get a static string from either Guile or Python. The problem applies to both qof_query_search_for and qof_query_create_for. The straight Guile wrappers don't work either: They just cast the SCM argument to a QofIdTypeConst and hand it over. That doesn't produce a usable char*. Naturally the non-working bindings aren't called anywhere. Actual code uses qof-query-create-for-splits and qof-query-create-for-invoices (engine.i and business-core.i, respectively; neither exported to Python) and the elaborate gnc_scm2query_v2 in engine-helpers.c that gets the string value from an SCM symbol, converts it to UTF8, strdups that to pass to qof_query_search_for, *then frees the search_for string*. It's pure luck if the query gets run before the string location is overwritten. Fortunately it's used only in the register report. The simplest solution is to strdup the QofIdType and free it when it's replaced or the query is destroyed.
Christoff Holterman has devised a work-around for Python to fix bug 796137. This is technically a duplicate of that but covers both Python and Guile so I'm leaving this open.