PR #2187 made GncPrice.get_value() return a GncNumeric wrapper and clone() a
fully wrapped GncPrice. The price example scripts still used the pre-5.15 raw
_gnc_numeric idiom and broke -- reported as Bug 799796 (cloned prices silently
kept the original value).
Example scripts (bindings/python/example_scripts/):
* quotes_historic.py -- reworked to the modern idiom; it now actually runs on
5.x (it had further latent breakage beyond the reported one):
- Construct each price directly with GncPrice(book) + setters instead of
cloning an existing price, so the script no longer needs a pre-existing
price in the book. Look the pricing currency (USD) up from the commodity
table rather than deriving it from a split.
- Build the value with the double->GncNumeric constructor at GnuCash's
standard price precision -- the pricing currency's SCU * COMMODITY_DENOM_MULT
rounded HALF_UP (gnc-pricedb.h "Price policy") -- dropping the
Fraction.from_float().limit_denominator(100000) dance and its import.
- Set the source with the PriceSource enum -- set_source(PriceSource.FINANCE_QUOTE)
(the enum added in #2317). The original set_source("Finance::Quotes::Historic")
passed a string to what has been an enum setter since 2.6, which raises
TypeError on modern bindings.
- Open with Session(url), which defaults to SESSION_NORMAL_OPEN. The old
Session(url, True, False, False) passed the deprecated ignore_lock=True,
silently bypassing the book's lock file.
* priceDB_test.py, price_database_example.py -- num/denom are methods now, so
read v.num() / v.denom().
Prevent silent recurrence (gnucash_core.py):
The write path failed *silently*, which is how this slipped through review and
CI. num/denom are read-only accessor methods, so assigning to them merely
shadows the method and changes nothing. Add a GncNumeric.__setattr__ that raises
AttributeError on assignment to num/denom, pointing at the correct idiom
GncNumeric(num, denom).
Test (bindings/python/tests/test_numeric.py):
New test_num_denom_read_only covering the guard. It needs no backend, so it runs
in the existing python-bindings CTest on all platforms.
The wiki page Stocks/get_prices, which the reporter copied from, is being
updated separately.
addAccount was rewritten to accept (name, currency, account_type_id,
parent_account_guid, description, code), validate each field, look up
the parent by GUID, and return gnucash_simple.accountToDict(account).
The route handler was updated to pull the form fields and call it with the
new signature.
README was updated to reflect these changes.
Many Python binding methods silently returned raw SwigPyObject pointers
instead of proper Python wrapper objects because the methods_return_instance
dicts were incomplete. This adds the missing entries and activates the
DeprecationWarning in the SWIG typemap fallback path from PR 1.
Return-type wrapping fixes (gnucash_core.py):
GncPrice (new dict — no wrapping existed before):
get_commodity → GncCommodity, get_currency → GncCommodity,
clone → GncPrice, get_value → GncNumeric
GncPriceDB (added to existing dict):
nth_price → GncPrice, lookup_day_t64 → GncPrice,
convert_balance_nearest_before_price_t64 → GncNumeric
GncPriceDB (new list wrapping):
lookup_latest_any_currency → list[GncPrice],
lookup_nearest_before_any_currency_t64 → list[GncPrice],
lookup_nearest_in_time_any_currency_t64 → list[GncPrice]
GncCommodity: obtain_twin → GncCommodity,
get_namespace_ds → GncCommodityNamespace
Account: get_currency_or_parent → GncCommodity,
GetLotList → list[GncLot]
GncLot: get_split_list → list[Split]
Example script cleanup:
Remove type(x).__name__ == 'SwigPyObject' workarounds from
gnc_convenience.py, gncinvoicefkt.py, str_methods.py — these are
no longer needed now that methods return proper wrapper objects.
SWIG typemap (gnucash_core.i):
Activate DeprecationWarning on the .instance fallback path, replacing
the TODO placeholder from the typemap compatibility layer commit.
New test file (test_price_and_wrapping.py):
18 tests covering all wrapping fixes and typemap compatibility,
using in-repo test data (pricedb1.gml2, sample1.gnucash).
Tests auto-skip when XML backend is unavailable.
The root cause of which is that on recent releases of GLib (recent
meaning 2.66 in the current Debian stable!) g_type_instance_get_private
looks in the wrong place for the private data. When running the script
in question it returned NULL and since the code didn't check for a valid
pointer, it crashed.
So this change replaces all calls to g_type_instance_get_private with
the function [type_prefix]_get_instance_private() added in glib-2.36
except for two register2 files that have been removed from master; those
are ignored to avoid unnecessary merge conflicts.
Python bindings already have some wrapping objects for
qof predicates. This adds the one missing for GncNumeric
comparisons.
Additionally fixes a wrong number for QOF_NUMERIC_MATCH_ANY
in example file.
>>> nominator='123456'
A digit is missing in the string returned from to_string_with_decimal_point_placed. The -1 error.
>>> point_place=2
>>> nominator[:-point_place - 1], nominator[-point_place:]
('123', '56')
There are more, but these are most common ones.
There are also a number of urls that don't behave well when https, so those are skipped
At some point I have also started marking non-working URLs as [DEAD LINK], though
that's not a full coverage.