Hi All, "PR1" in the below plan is addressed with: https://github.com/Gnucash/gnucash/pull/2186
And I decided to do both "PR2" and "PR3" as: https://github.com/Gnucash/gnucash/pull/2187 I look forward to your thoughts. Cheers, Noah > On Feb 9, 2026, at 11:22 AM, [email protected] wrote: > > John, > Thanks for the guidance on SWIG typemaps -- while new to me, after > some learning, I think that's the right mechanism and I appreciate you > pointing me in that direction. The Python bindings barely use input > typemaps today, so there's a real opportunity to improve the > infrastructure here. > After studying the existing typemap patterns in the codebase (the > GncOwner input/output typemaps in gnucash_core.i, the time64 > multi-type acceptance in time64.i, and the GList output typemap in > base-typemaps.i), I believe we can do this with no breaking changes > and no need for deprecation. The approach is a %typemap(in) for each > pointer type that tries the normal SWIG pointer conversion first, and > only if that fails, checks for a .instance attribute (which is how the > Python wrapper classes store their underlying SWIG pointer). The > normal code path has zero overhead -- the fallback only triggers when > someone passes a wrapper object to a gnucash_core_c function (and we > could introduce a deprecation warning in this pathway). > I'm estimating three PRs: > PR 1 -- SWIG typemap compatibility layer. A %define macro > (GNC_ACCEPT_WRAPPER) in gnucash_core.i that generates input typemaps > for each core pointer type (GNCPrice *, gnc_commodity *, Account *, > Split *, etc.). This is pure infrastructure -- no behavior changes, no > risk. Includes tests verifying that wrapper objects are accepted by > gnucash_core_c functions. > PR 2 -- Fix the return-type wrapping. Add the missing > methods_return_instance dict entries for GncPrice, GncPriceDB, > GncCommodity, Account, and GncLot. With the typemaps from PR 1 in > place, both old-style (gnucash_core_c direct calls) and new-style > (wrapper methods) code works. Includes tests for each newly-wrapped > method. > PR 3 -- Clean up example scripts. Remove the type(x).__name__ == > 'SwigPyObject' workarounds from the shipped examples > (gnc_convenience.py, gncinvoicefkt.py, str_methods.py). > PRs 1 and 2 could both target 5.15 (except I have no idea the timeline > for that). I'll start with PR 1. > 5.16 or later: Optionally remove the fallback to pointer, or just > leave it forever since it costs nothing > Cheers, > Noah > ---------------------------------------------------------------------- > > Message: 1 > Date: Sat, 7 Feb 2026 13:56:12 -0800 > From: [email protected] > To: [email protected] > Subject: Python bindings -- many methods return raw SWIG pointers > instead of wrapped Python objects > Message-ID: <[email protected]> > Content-Type: text/plain; charset="UTF-8" > > Hi All, > I've been a happy GnuCash user for 13 years and am recently finding > more time and interest to take on some more advanced use cases and > also contribute to the GnuCash project. (and more bandwidth thanks to > AI assisted coding) > > My projects all involve use of the official API python bindings. So > you'll see some bug reports, PR, and other chatter from me about that. > > Here's a matter that's within my skillet to fix, but the best approach > is debatable given one route involves breaking changes to the existing > python bindings. So I wanted to seek other's opinions. > > Background > ----------------------------- > > The Python bindings use a two-layer architecture: SWIG auto-generates > a low-level C API (gnucash_core_c), and gnucash_core.py wraps selected > methods so they return proper Python objects (GncPrice, GncCommodity, > etc.) instead of raw SWIG pointers. This wrapping is done via > methods_return_instance() dicts that map method names to their return > types. > > The problem is that these dicts are incomplete. Many methods that > return pointers to GnuCash objects are exposed on the Python classes > (via add_methods_with_prefix) but never registered for return-type > wrapping. They silently return raw SwigPyObject pointers that have no > Python methods and can only be used via gnucash_core_c C-level > function calls. > > This is confusing because the methods *appear* to work -- they're > callable and return non-None values -- but the return values are > unusable through the documented Python API. There's no error, no > warning, and no documentation indicating which methods are wrapped and > which aren't. The only way to discover the problem is to inspect > type() on the return value. > > I've done a systematic audit of all classes in gnucash_core.py and > gnucash_business.py, cross-referencing the C functions exposed by SWIG > against the methods_return_instance dicts, and empirically verified > each finding. Below are the results. > > > Affected Classes and Methods > ----------------------------- > > 1. GncPrice -- no wrapping dict exists at all > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > GncPrice is the worst case. bindings/python/gnucash_core.py line 741 > calls add_methods_with_prefix('gnc_price_'), which exposes all > gnc_price_* functions as methods. But there is no > methods_return_instance call for GncPrice anywhere in that file -- not > a single method has its return type wrapped. > > Method Currently returns Should return > ---------------- -------------------------------- ---------------- > get_commodity() SwigPyObject (raw gnc_commodity *) GncCommodity > get_currency() SwigPyObject (raw gnc_commodity *) GncCommodity > clone(book) SwigPyObject (raw GNCPrice *) GncPrice > get_value() _gnc_numeric (SWIG proxy) GncNumeric > > get_value() is a partial case -- the _gnc_numeric SWIG proxy is usable > via GncNumeric(instance=val), but this is inconsistent with Split and > Transaction where equivalent methods (GetAmount, GetValue, GetBalance, > etc.) are all wrapped to return GncNumeric directly. > > Suggested fix: > > GncPrice.add_methods_with_prefix('gnc_price_') > > gnc_price_dict = { > 'get_commodity': GncCommodity, > 'get_currency': GncCommodity, > 'clone': GncPrice, > 'get_value': GncNumeric, > } > methods_return_instance(GncPrice, gnc_price_dict) > > > 2. GncPriceDB -- PriceDB_dict incomplete > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > The existing PriceDB_dict wraps lookup_latest, > lookup_nearest_in_time64, lookup_nearest_before_t64, and some > convert_balance methods. But several methods that return the same > types are missing. > > Missing single-value wrappers (should return GncPrice): > > Method Currently returns > Should return > ---------------------------------------- ------------------------ > ----------- > nth_price(commodity, n) SwigPyObject (GNCPrice *) > GncPrice > lookup_day_t64(commodity, currency, date) SwigPyObject (GNCPrice *) > GncPrice > > Missing single-value wrapper (should return GncNumeric): > > Method Currently returns > Should return > ----------------------------------------------- -------------------- > ----------- > convert_balance_nearest_before_price_t64(...) _gnc_numeric (raw) > GncNumeric > > Its siblings convert_balance_latest_price and > convert_balance_nearest_price_t64 are correctly wrapped. > > Missing list wrappers (should return list of GncPrice): > > Method Currently returns > Should return > -------------------------------------------------- > --------------------- ---------------- > lookup_latest_any_currency(commodity) > list[SwigPyObject] list[GncPrice] > lookup_nearest_before_any_currency_t64(comm, date) > list[SwigPyObject] list[GncPrice] > lookup_nearest_in_time_any_currency_t64(comm, date) > list[SwigPyObject] list[GncPrice] > > Note: get_latest_price, get_nearest_price, and get_nearest_before_price > are NOT bugs -- their C functions return gnc_numeric directly (the > price value, not a GNCPrice *), so the raw _gnc_numeric return is the > correct C type. They should arguably be wrapped to GncNumeric for > consistency, but that's a lower priority. > > Suggested fix: > > PriceDB_dict = { > 'lookup_latest': GncPrice, > 'lookup_nearest_in_time64': GncPrice, > 'lookup_nearest_before_t64': GncPrice, > 'nth_price': GncPrice, > 'lookup_day_t64': GncPrice, > 'convert_balance_latest_price': GncNumeric, > 'convert_balance_nearest_price_t64': GncNumeric, > 'convert_balance_nearest_before_price_t64': GncNumeric, > 'get_latest_price': GncNumeric, > 'get_nearest_price': GncNumeric, > 'get_nearest_before_price': GncNumeric, > } > methods_return_instance(GncPriceDB, PriceDB_dict) > > methods_return_instance_lists(GncPriceDB, { > 'get_prices': GncPrice, # already done > 'lookup_latest_any_currency': GncPrice, # new > 'lookup_nearest_before_any_currency_t64': GncPrice, # new > 'lookup_nearest_in_time_any_currency_t64': GncPrice, # new > }) > > > 3. GncCommodity -- two missing wrappers > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > GncCommodity.clone is correctly wrapped (gnucash_core.py line 979), > but two other methods that return object pointers are not. > > Method Currently returns Should > return > ------------------ ----------------------------------------- > ---------------------- > obtain_twin(book) SwigPyObject (raw gnc_commodity *) > GncCommodity > get_namespace_ds() SwigPyObject (raw gnc_commodity_namespace *) > GncCommodityNamespace > > Additionally, get_quote_source() and get_default_quote_source() return > raw gnc_quote_source * pointers. However, gnc_quote_source has no > Python wrapper class, so these are a deeper design gap rather than a > simple omission -- there's nothing to wrap *to*. Currently the only > way to use them is via > gnucash_core_c.gnc_quote_source_get_internal_name(ptr) > etc. A proper fix would require creating a new GncQuoteSource wrapper > class. > > > 4. Account -- one missing wrapper > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > Method Currently returns Should > return > ------------------------ -------------------------------- ------------ > get_currency_or_parent() SwigPyObject (raw gnc_commodity *) GncCommodity > > The existing account_dict wraps GetCommodity -> GncCommodity but > misses get_currency_or_parent, which returns the same C type. > > > 5. GncLot -- two missing wrappers > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > Method Currently returns Should return > ---------------------- --------------------- --------------- > get_balance_before(sp) raw _gnc_numeric GncNumeric > get_split_list() list[SwigPyObject] list[Split] > > The existing gnclot_dict wraps get_balance -> GncNumeric but misses > get_balance_before. And get_split_list needs > method_function_returns_instance_list like Account.GetSplitList and > Transaction.GetSplitList already have. > > > The Breaking Change Problem > --------------------------- > > Every fix listed above changes a method's return type from a raw SWIG > pointer to a wrapped Python object. These are breaking changes: any > existing code that passes these return values to gnucash_core_c > C-level functions will break, because those functions expect the raw > SWIG pointer, not a wrapper. > > For example, current workaround code looks like: > > from gnucash import gnucash_core_c as gc > > raw_price = pricedb.nth_price(commodity, 0) > gc.gnc_price_get_currency(raw_price) # works today > gc.gnc_price_get_time64(raw_price) > > After wrapping nth_price -> GncPrice: > > price = pricedb.nth_price(commodity, 0) # now returns GncPrice > gc.gnc_price_get_currency(price) # BREAKS > price.get_currency() # new correct usage > > The workaround-after-the-fix is to use .instance to extract the raw > pointer: > > gc.gnc_price_get_currency(price.instance) # works > > How many users are affected? > > Anyone using these methods today has already discovered the raw-pointer > problem through trial and error and written gnucash_core_c workarounds. > These workarounds are undocumented and fragile. The "break" moves users > from an undocumented workaround to the intended API. > > That said, the Python bindings have been in this state for years, and > scripts using the C-level workarounds do exist in the wild (Stack > Overflow answers, wiki examples, personal scripts). > > > Possible Approaches > ------------------- > > I'd like the developers' input on how to handle this. Some options: > > Option A: Fix everything, accept the break > > Add all missing entries to the methods_return_instance dicts. > Document the change in release notes. This is the cleanest long-term > outcome but breaks existing workaround code silently (no error -- > just wrong types passed to C functions, likely causing segfaults or > TypeError). > > Option B: Fix everything, add a compatibility shim > > Modify method_function_returns_instance (in function_class.py) so > that wrapped objects are transparently accepted by gnucash_core_c > functions. This could be done by making the wrapper classes implement > __swig_convert__ or by patching process_list_convert_to_instance to > unwrap at call boundaries. This would make both old and new code > work, but adds complexity to the wrapping layer. > > Option C: Fix only the most impactful methods, leave the rest > > Prioritize the methods most likely to be encountered by users: > - GncPrice.get_commodity(), .get_currency() > - GncPriceDB.nth_price() > - Account.get_currency_or_parent() > > Leave edge cases like GncLot.get_balance_before() and > GncCommodity.obtain_twin() for later. > > Option D: Deprecation warnings first, fix later > > Add runtime deprecation warnings when unwrapped methods are called, > pointing users to the upcoming change. Fix the return types in the > next major release. > > --- > > My preference is Option A with clear release notes because the > compatibility shim may be too complex. The current state is a usability > trap -- methods look like they work but return unusable objects -- and > fixing it benefits all future users even if it inconveniences the few > who have written workarounds. > > I'm happy to submit patches for whichever approach the project prefers. > > > Appendix: Methodology > --------------------- > > All findings were verified empirically on GnuCash 5.14 built from > source (Python 3.11, Debian Bookworm, -DWITH_PYTHON=ON > -DWITH_GNUCASH=OFF). Each method was called against a test GnuCash > SQLite file containing accounts, commodities, and prices. Return types > were checked with type() and compared against the C function signatures > in gnc-pricedb.h, gnc-commodity.h, Account.h, and gnc-lot.h. > > The full C API surface was enumerated via dir(gnucash_core_c) and > cross-referenced against the methods_return_instance dicts in > gnucash_core.py (lines 769-776, 960-974, 984-992, 1011-1020, > 1029-1044, 1056-1074, 1085-1114) and gnucash_business.py. > > > Sincerely, > > Noah Reddell > > > ------------------------------ > > Message: 2 > Date: Sat, 7 Feb 2026 15:40:07 -0800 > From: John Ralls <[email protected]> > To: [email protected] > Cc: [email protected] > Subject: Re: Python bindings -- many methods return raw SWIG pointers > instead of wrapped Python objects > Message-ID: <[email protected]> > Content-Type: text/plain; charset=utf-8 > > > > > On Feb 7, 2026, at 13:56, [email protected] wrote: > > > > Hi All, > > I've been a happy GnuCash user for 13 years and am recently finding > > more time and interest to take on some more advanced use cases and > > also contribute to the GnuCash project. (and more bandwidth thanks to > > AI assisted coding) > > > > My projects all involve use of the official API python bindings. So > > you'll see some bug reports, PR, and other chatter from me about that. > > > > Here's a matter that's within my skillet to fix, but the best approach > > is debatable given one route involves breaking changes to the existing > > python bindings. So I wanted to seek other's opinions. > > > > Background > > ----------------------------- > > > > The Python bindings use a two-layer architecture: SWIG auto-generates > > a low-level C API (gnucash_core_c), and gnucash_core.py wraps selected > > methods so they return proper Python objects (GncPrice, GncCommodity, > > etc.) instead of raw SWIG pointers. This wrapping is done via > > methods_return_instance() dicts that map method names to their return > > types. > > > > The problem is that these dicts are incomplete. Many methods that > > return pointers to GnuCash objects are exposed on the Python classes > > (via add_methods_with_prefix) but never registered for return-type > > wrapping. They silently return raw SwigPyObject pointers that have no > > Python methods and can only be used via gnucash_core_c C-level > > function calls. > > > > This is confusing because the methods *appear* to work -- they're > > callable and return non-None values -- but the return values are > > unusable through the documented Python API. There's no error, no > > warning, and no documentation indicating which methods are wrapped and > > which aren't. The only way to discover the problem is to inspect > > type() on the return value. > > > > I've done a systematic audit of all classes in gnucash_core.py and > > gnucash_business.py, cross-referencing the C functions exposed by SWIG > > against the methods_return_instance dicts, and empirically verified > > each finding. Below are the results. > > > > > > Affected Classes and Methods > > ----------------------------- > > > > 1. GncPrice -- no wrapping dict exists at all > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > GncPrice is the worst case. bindings/python/gnucash_core.py line 741 > > calls add_methods_with_prefix('gnc_price_'), which exposes all > > gnc_price_* functions as methods. But there is no > > methods_return_instance call for GncPrice anywhere in that file -- not > > a single method has its return type wrapped. > > > > Method Currently returns Should return > > ---------------- -------------------------------- ---------------- > > get_commodity() SwigPyObject (raw gnc_commodity *) GncCommodity > > get_currency() SwigPyObject (raw gnc_commodity *) GncCommodity > > clone(book) SwigPyObject (raw GNCPrice *) GncPrice > > get_value() _gnc_numeric (SWIG proxy) GncNumeric > > > > get_value() is a partial case -- the _gnc_numeric SWIG proxy is usable > > via GncNumeric(instance=val), but this is inconsistent with Split and > > Transaction where equivalent methods (GetAmount, GetValue, GetBalance, > > etc.) are all wrapped to return GncNumeric directly. > > > > Suggested fix: > > > > GncPrice.add_methods_with_prefix('gnc_price_') > > > > gnc_price_dict = { > > 'get_commodity': GncCommodity, > > 'get_currency': GncCommodity, > > 'clone': GncPrice, > > 'get_value': GncNumeric, > > } > > methods_return_instance(GncPrice, gnc_price_dict) > > > > > > 2. GncPriceDB -- PriceDB_dict incomplete > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > The existing PriceDB_dict wraps lookup_latest, > > lookup_nearest_in_time64, lookup_nearest_before_t64, and some > > convert_balance methods. But several methods that return the same > > types are missing. > > > > Missing single-value wrappers (should return GncPrice): > > > > Method Currently returns > > Should return > > ---------------------------------------- ------------------------ > > ----------- > > nth_price(commodity, n) SwigPyObject (GNCPrice *) > GncPrice > > lookup_day_t64(commodity, currency, date) SwigPyObject (GNCPrice *) > GncPrice > > > > Missing single-value wrapper (should return GncNumeric): > > > > Method Currently returns > > Should return > > ----------------------------------------------- -------------------- > > ----------- > > convert_balance_nearest_before_price_t64(...) _gnc_numeric (raw) > > GncNumeric > > > > Its siblings convert_balance_latest_price and > > convert_balance_nearest_price_t64 are correctly wrapped. > > > > Missing list wrappers (should return list of GncPrice): > > > > Method Currently returns > > Should return > > -------------------------------------------------- > > --------------------- ---------------- > > lookup_latest_any_currency(commodity) > > list[SwigPyObject] list[GncPrice] > > lookup_nearest_before_any_currency_t64(comm, date) > > list[SwigPyObject] list[GncPrice] > > lookup_nearest_in_time_any_currency_t64(comm, date) > > list[SwigPyObject] list[GncPrice] > > > > Note: get_latest_price, get_nearest_price, and get_nearest_before_price > > are NOT bugs -- their C functions return gnc_numeric directly (the > > price value, not a GNCPrice *), so the raw _gnc_numeric return is the > > correct C type. They should arguably be wrapped to GncNumeric for > > consistency, but that's a lower priority. > > > > Suggested fix: > > > > PriceDB_dict = { > > 'lookup_latest': GncPrice, > > 'lookup_nearest_in_time64': GncPrice, > > 'lookup_nearest_before_t64': GncPrice, > > 'nth_price': GncPrice, > > 'lookup_day_t64': GncPrice, > > 'convert_balance_latest_price': GncNumeric, > > 'convert_balance_nearest_price_t64': GncNumeric, > > 'convert_balance_nearest_before_price_t64': GncNumeric, > > 'get_latest_price': GncNumeric, > > 'get_nearest_price': GncNumeric, > > 'get_nearest_before_price': GncNumeric, > > } > > methods_return_instance(GncPriceDB, PriceDB_dict) > > > > methods_return_instance_lists(GncPriceDB, { > > 'get_prices': GncPrice, # already > done > > 'lookup_latest_any_currency': GncPrice, # new > > 'lookup_nearest_before_any_currency_t64': GncPrice, # new > > 'lookup_nearest_in_time_any_currency_t64': GncPrice, # new > > }) > > > > > > 3. GncCommodity -- two missing wrappers > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > GncCommodity.clone is correctly wrapped (gnucash_core.py line 979), > > but two other methods that return object pointers are not. > > > > Method Currently returns Should > return > > ------------------ ----------------------------------------- > > ---------------------- > > obtain_twin(book) SwigPyObject (raw gnc_commodity *) > GncCommodity > > get_namespace_ds() SwigPyObject (raw gnc_commodity_namespace *) > > GncCommodityNamespace > > > > Additionally, get_quote_source() and get_default_quote_source() return > > raw gnc_quote_source * pointers. However, gnc_quote_source has no > > Python wrapper class, so these are a deeper design gap rather than a > > simple omission -- there's nothing to wrap *to*. Currently the only > > way to use them is via > gnucash_core_c.gnc_quote_source_get_internal_name(ptr) > > etc. A proper fix would require creating a new GncQuoteSource wrapper > > class. > > > > > > 4. Account -- one missing wrapper > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > Method Currently returns Should > return > > ------------------------ -------------------------------- > ------------ > > get_currency_or_parent() SwigPyObject (raw gnc_commodity *) > GncCommodity > > > > The existing account_dict wraps GetCommodity -> GncCommodity but > > misses get_currency_or_parent, which returns the same C type. > > > > > > 5. GncLot -- two missing wrappers > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > Method Currently returns Should return > > ---------------------- --------------------- --------------- > > get_balance_before(sp) raw _gnc_numeric GncNumeric > > get_split_list() list[SwigPyObject] list[Split] > > > > The existing gnclot_dict wraps get_balance -> GncNumeric but misses > > get_balance_before. And get_split_list needs > > method_function_returns_instance_list like Account.GetSplitList and > > Transaction.GetSplitList already have. > > > > > > The Breaking Change Problem > > --------------------------- > > > > Every fix listed above changes a method's return type from a raw SWIG > > pointer to a wrapped Python object. These are breaking changes: any > > existing code that passes these return values to gnucash_core_c > > C-level functions will break, because those functions expect the raw > > SWIG pointer, not a wrapper. > > > > For example, current workaround code looks like: > > > > from gnucash import gnucash_core_c as gc > > > > raw_price = pricedb.nth_price(commodity, 0) > > gc.gnc_price_get_currency(raw_price) # works today > > gc.gnc_price_get_time64(raw_price) > > > > After wrapping nth_price -> GncPrice: > > > > price = pricedb.nth_price(commodity, 0) # now returns GncPrice > > gc.gnc_price_get_currency(price) # BREAKS > > price.get_currency() # new correct usage > > > > The workaround-after-the-fix is to use .instance to extract the raw > > pointer: > > > > gc.gnc_price_get_currency(price.instance) # works > > > > How many users are affected? > > > > Anyone using these methods today has already discovered the raw-pointer > > problem through trial and error and written gnucash_core_c workarounds. > > These workarounds are undocumented and fragile. The "break" moves users > > from an undocumented workaround to the intended API. > > > > That said, the Python bindings have been in this state for years, and > > scripts using the C-level workarounds do exist in the wild (Stack > > Overflow answers, wiki examples, personal scripts). > > > > > > Possible Approaches > > ------------------- > > > > I'd like the developers' input on how to handle this. Some options: > > > > Option A: Fix everything, accept the break > > > > Add all missing entries to the methods_return_instance dicts. > > Document the change in release notes. This is the cleanest long-term > > outcome but breaks existing workaround code silently (no error -- > > just wrong types passed to C functions, likely causing segfaults or > > TypeError). > > > > Option B: Fix everything, add a compatibility shim > > > > Modify method_function_returns_instance (in function_class.py) so > > that wrapped objects are transparently accepted by gnucash_core_c > > functions. This could be done by making the wrapper classes implement > > __swig_convert__ or by patching process_list_convert_to_instance to > > unwrap at call boundaries. This would make both old and new code > > work, but adds complexity to the wrapping layer. > > > > Option C: Fix only the most impactful methods, leave the rest > > > > Prioritize the methods most likely to be encountered by users: > > - GncPrice.get_commodity(), .get_currency() > > - GncPriceDB.nth_price() > > - Account.get_currency_or_parent() > > > > Leave edge cases like GncLot.get_balance_before() and > > GncCommodity.obtain_twin() for later. > > > > Option D: Deprecation warnings first, fix later > > > > Add runtime deprecation warnings when unwrapped methods are called, > > pointing users to the upcoming change. Fix the return types in the > > next major release. > > > > --- > > > > My preference is Option A with clear release notes because the > > compatibility shim may be too complex. The current state is a usability > > trap -- methods look like they work but return unusable objects -- and > > fixing it benefits all future users even if it inconveniences the few > > who have written workarounds. > > > > I'm happy to submit patches for whichever approach the project prefers. > > > > > > Appendix: Methodology > > --------------------- > > > > All findings were verified empirically on GnuCash 5.14 built from > > source (Python 3.11, Debian Bookworm, -DWITH_PYTHON=ON > > -DWITH_GNUCASH=OFF). Each method was called against a test GnuCash > > SQLite file containing accounts, commodities, and prices. Return types > > were checked with type() and compared against the C function signatures > > in gnc-pricedb.h, gnc-commodity.h, Account.h, and gnc-lot.h. > > > > The full C API surface was enumerated via dir(gnucash_core_c) and > > cross-referenced against the methods_return_instance dicts in > > gnucash_core.py (lines 769-776, 960-974, 984-992, 1011-1020, > > 1029-1044, 1056-1074, 1085-1114) and gnucash_business.py. > > > > > Thanks for being willing to take this on. > > Unfortunately we have no idea how many python bindings users there are nor > how sophisticated any of them are about working around the bindings? > limitations. Our general policy is that we wouldn?t remove API without at > least a release or two worth of notice via deprecation warnings, so if we > got deprecations in the upcoming 5.15 release we?d wait until the end of > the year to remove the API. It?s also not ideal to deprecate API before the > replacement is available making your option B the best choice. > > The breakage problem seems to me to be what SWIG typemaps are for, and it > looks to me like the python bindings don?t make much use of typemaps. Did > you consider that and if not can you? > > Regards, > John Ralls > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > gnucash-devel mailing list > [email protected] > https://lists.gnucash.org/mailman/listinfo/gnucash-devel > > > ------------------------------ > > End of gnucash-devel Digest, Vol 20, Issue 7 > ******************************************** >
_______________________________________________ gnucash-devel mailing list [email protected] https://lists.gnucash.org/mailman/listinfo/gnucash-devel
