Commit Graph
62 Commits
Author SHA1 Message Date
John Ralls 3cf1352cbb Merge Noah Noerr's 'python-guard-price-set-source-string' into stable. 2026-09-25 16:10:42 -07:00
Noerr 0dc41c1212 [bindings/python] Deprecate set_source_string; remove it from the Guile bindings
gnc_price_set_source_string maps a source string to the PriceSource enum and
silently leaves the source unchanged for anything it doesn't recognize -- a
silent no-op a naive Python or Guile script can hit. Steer callers to
set_source() with a PriceSource member (added in #2317) instead.

Python bindings:
- Deprecate GncPrice.set_source_string(): it now emits a DeprecationWarning
  pointing at set_source(PriceSource.<...>). It still works during the
  deprecation period and still guards -- if the string is not recognized (the
  round-tripped source no longer equals the input) it raises ValueError rather
  than silently doing nothing.
- Fix the deprecated() decorator in deprecation.py: it referenced the undefined
  DeprecationWarnig and inspect.current_frame(), so it raised instead of
  warning (the one existing @deprecated use was latently broken).

Guile bindings:
- mark gnc-price-set-source-string deprecated in engine.i.
  (Python and Guile use separate SWIG interface files, so Python is
  handled separately). The only in-tree Guile caller is the QIF importer, updated to
  gnc-price-set-source with PRICE-SOURCE-USER-PRICE; the redundant
  set-source-string in test-engine-extras.scm's fixture helper is dropped.

Tests (test_price_and_wrapping.py):
- TestSetSourceStringGuard covers the guard (still raises on an unrecognized
  string) and the new DeprecationWarning.

Removing set_source_string from the Python bindings is a follow-up.
2026-09-25 16:05:19 -07:00
Noerr 89448ffd34 [bindings/python] Fix and modernize the price example scripts (Bug 799796)
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.
2026-09-24 22:08:37 -07:00
Noerr f21fec06be [bindings/python] Add a PriceSource enum for gnc_price_set_source()
Setting a price's source from Python meant reaching into gnucash_core_c for the
raw PRICE_SOURCE_* constants. Add a PriceSource(IntEnum) alongside SessionOpenMode,
with values sourced from the C enum (via gnucash_core_c) so they can't drift, so a
script can write price.set_source(PriceSource.FINANCE_QUOTE) with a plain top-level
import.

Add test_price_and_wrapping.TestPriceSourceEnum:
 - test_values_match_c_enum asserts the Python enum covers the C PRICE_SOURCE_*
   value set exactly, so adding, removing, or renumbering a C value fails CI until
   PriceSource is updated to match. (Member names are a Python-side choice --
   FINANCE_QUOTE spells out FQ -- so the check is on values.)
 - test_set_source_accepts_enum confirms a member flows through set_source() and
   round-trips.
2026-09-24 00:41:54 -07:00
John Ralls cb6b140805 Merge Oliver Lok Trevor's 'fix-glist-python-bindings' into stable 2026-06-25 17:40:12 -07:00
Noah R 3e98c5d8c8 [engine] Add first-class online_id accessors for Split and Account
Promote the OFX/HBCI online_id to named engine accessors:
  xaccSplitGetOnlineID / SetOnlineID / HasOnlineID
  xaccAccountGetOnlineID / SetOnlineID
The getters return an instance-owned const char* (mirroring
xaccTransGetDocLink / xaccTransGetNotes), so the existing
add_methods_with_prefix auto-wrapper exposes them in the Python bindings
with no .i changes and no %newobject.  They write to the same engine KVP
slot ("online_id") the desktop importer uses, so there is no data or
behavior change.

With the accessors in place the gnc_import_*_online_id wrappers in
import-utilities are redundant, so replace every call site (OFX,
AqBanking, and the generic matcher/backend) with them, delete
import-utilities.cpp, and drop the online_id declarations from
import-utilities.h (its importer preference-key macros are retained).

- The engine getters return an instance-owned const char* instead of a
  g_strdup'd copy, so callers no longer free the result; the affected
  locals are retyped const and their g_free()s dropped.
  hash_account_online_ids() g_strdups before inserting, since its hash
  table owns its keys (g_free key-destructor).
- xaccAccountSetOnlineID(acc, "") clears the slot, matching the OFX
  "delete the online_id" intent (the old wrapper stored an empty string).
- Drop the two unused wrappers: gnc_import_set_trans_online_id (marked
  "Not actually used") and gnc_import_trans_has_online_id (no callers).
- Add xaccSplitGet/SetOnlineID to the Split gmock so test-import-backend
  links without import-utilities.
2026-06-21 16:43:03 -07:00
Oliver Lok Trevor 115ef7f657 Added unit test. 2026-04-28 17:39:32 -04:00
Noah R 859f0839ce [python-bindings] Add Split wrapping fixes, refactor tests for CI
Add missing gnc_numeric wrapping for two Split methods:
  - GetNoclosingBalance → GncNumeric
  - GetCapGains → GncNumeric

Refactor test_price_and_wrapping.py to create all test data
programmatically in in-memory sessions, eliminating external data file
dependencies (pricedb1.gml2, sample1.gnucash) and XML backend
requirement. All 27 tests now run unconditionally.

Register tests in CI: add imports to runTests.py.in and add
test_price_and_wrapping.py to CMakeLists.txt dist list.
2026-03-06 15:05:30 -08:00
Noah R 556e7b0d70 [python-bindings] Add get_*_price GncNumeric wrapping, double-wrap protection, and tests
Wrap GncPriceDB.get_latest_price, get_nearest_price, and
get_nearest_before_price to return GncNumeric instead of raw
_gnc_numeric SWIG proxies.

Add double-wrap safety in ClassFromFunctions.__init__: if a wrapper
object is passed as instance=, unwrap it to the underlying SWIG proxy.
This prevents breakage when callers re-wrap a return value that changed
from a raw SWIG proxy to a wrapper class, e.g.
GncNumeric(instance=pricedb.get_latest_price(...)).

New tests:
  TestGetPriceReturnsGncNumeric (4 tests):
    get_latest_price, get_nearest_price, get_nearest_before_price
    return GncNumeric; arithmetic works on the result.
  TestDoubleWrapProtection (4 tests):
    GncNumeric, GncCommodity double-wrap; raw SWIG proxy still works.
2026-03-06 14:18:25 -08:00
Noah R 592b57ddbb [python-bindings] Fix missing return-type wrapping and clean up examples
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.
2026-03-06 12:53:56 -08:00
Oliver Lok Trevor 008980c497 Added unit test 2025-04-24 20:02:54 -04:00
John Ralls a3f14759ab Asan: Make leak and ODR violation reporting CMake options.
pass -DLEAKS=ON or -DODR=ON to enable these features. They have an
effect only with CMAKE_BUILD_TYPE=Asan and don't work on Apple because
Apple clang doesn't enable them.
2023-11-25 11:17:14 -08:00
John Ralls 2234fa433e Add Asan build type that enables the Address and UB sanitizers.
Uses generator statements instead of CMAKE_<TYPE>_FLAGS_ASAN to support multiconfig generators like Xcode.
2023-11-02 12:58:46 -07:00
Geert Janssens 29b7a9099d Fix cmake warnings while searching for python
There is a new find module since cmake 3.12. Cmake 3.27 will start
emitting warnings if the old modules are still in use.

Current implementation supports both. As soon as we can bump our minimal
cmake version to 3.12, the old support code can be dropped as well.
2023-08-17 18:23:33 +02:00
Christopher Lam f1adb5da34 Merge branch 'TXN_TYPE-is-dynamic' xaccTransGetTxnType into maint #1201 2022-07-18 09:24:32 +08:00
Christopher Lam fd12d3900c [Transaction.c] use heuristics to determine txn->txn_type 2022-07-18 09:24:05 +08:00
John Ralls 426b30c37e Fix python tests dependencies
So that ninja check works from a clean build directory with Python enabled.
2022-07-16 16:36:46 -07:00
John Ralls 7d94ade599 [python]Remove non-namespace "All non-currency" fom namespace test. 2022-03-25 15:19:57 -07:00
John Ralls 9ad24321b4 Remove investment-type namespaces.
Leave it to users to categorize their non-currency commodities. In the
QIF importer default non-classifiable commodities to
GNC_COMMODITY_NS_NONCURRENCY.
2022-03-01 19:58:23 -08:00
Frank H. Ellenberger c7f842c081 Bug 684507 - commodity namespace should be localized 2022-03-01 19:58:11 -08:00
John Ralls b8552a8070 Fix python transaction test_date on Ubuntu-81.04.
Python3 there is too old for fromisoformat, use direct construction
instead.
2021-09-10 17:01:38 -07:00
John Ralls fcab298245 Add test for Transaction GetDate() in python bindings.
Pursuant to Bug 798284.
2021-09-10 13:26:59 -07:00
c-holtermann b9c6fc2876 add some unittests for python Session
test arguments, deprecated as well as new mode arguments
test creating a session with a new xml file using __init__()
and begin(). Test raising exception when opening nonexistent
file without respective mode setting.
2020-06-21 16:23:32 +02:00
c-holtermann 5833c5afcb add unittests for function_class
add tests for some existing function_class functionality.
Add tests for the keyword argument changes.
2020-06-21 16:23:32 +02:00
c-holtermann b13f40aeaf remove translation test 2020-05-28 20:55:15 +02:00
c-holtermann 9e678a421e remove debug stuff 2020-05-28 20:31:16 +02:00
c-holtermann 7bf38ef837 test info 2020-05-28 20:29:33 +02:00
c-holtermann ca21f32249 remove global gettext import 2020-05-28 20:21:31 +02:00
c-holtermann f788e59318 remove debug stuff (temporarily) 2020-05-28 18:51:01 +02:00
c-holtermann fc87e275fa further debugging 2020-05-28 18:51:01 +02:00
c-holtermann 8d429d8295 further debugging 2020-05-28 18:51:01 +02:00
c-holtermann 2c09fe4f44 debug on travis 2020-05-28 18:51:01 +02:00
c-holtermann 694e5a26ff add test for gettext 2020-05-28 18:50:55 +02:00
Christopher Lam 14ea5d9751 Merge branch 'maint' 2020-05-04 23:31:21 +08:00
John Ralls 6a3fabc30d Fix test failure for timezones west of the prime meridian.
The previous fix didn't calculate the comparison time correctly and
ended up in the wrong day because the GMT time is before the local time.

In the course of checking the corner-case timezones (Midway and
Kiritimati) I found an error in the GncDateTime calculation of the
neutral time, so fixed that too.
2020-05-02 15:35:13 -07:00
John Ralls b4177bc60a Fix transaction post_date being set to midnight local.
Reported for Invoices on gnucash-user. Checked all other uses of
xaccTransSetPostDateSecs(), fixed the ones that weren't passing an
already normalized time64. For Invoices change the post_date to also be
normalized so that it stays the same as the transaction post_date. That
also protects it from the displayed date changing depending on timezone.

The python binding invoice post_time test had to be changed to match.
2020-04-30 12:09:22 -07:00
John Ralls 3ca8fa1229 Merge branch 'maint' 2020-04-13 11:27:14 -07:00
John Ralls e1b0140357 Fix failed build of python tests and failed test in 3.10 tarball. 2020-04-12 13:43:00 -07:00
John Ralls fdfaca5575 Merge Christoph Holtermann's 'python-session-instance-constructor' into maint. 2020-04-06 12:05:21 -07:00
c-holtermann 4dcdec664a remove whitespace in parentheses (PEP 8) 2020-04-06 07:03:40 +02:00
c-holtermann 43cebedd3d tests for session 2020-04-06 07:03:40 +02:00
andygoblins 4502afad4f fix __eq__ in Split and Transaction
Compare guids with .Equal() when comparing Split and Transaction instances.
2020-02-29 17:44:55 -06:00
Christoph Holtermann 54cb3358ce add basic test for python query
add test for creating query object and setting search_for
related to Bug 796137 and fix in commit 1a7c5b9a32
2018-09-20 18:54:49 +02:00
Geert Janssens a9f35ed7ae Lowercase cmake commands
A huge bikeshed fest but it distracted me enough to do it anyway.
2018-05-03 23:18:15 +02:00
Julian Wollrath a43b115a45 Bug 791831 - Add python3 support
This switches swig to use python 3 specific features when generating the
bindings, switches the build over to python 3 and makes the neccesary
python 2 to 3 conversions in the bindings and tests.
2018-03-17 15:10:00 -07:00
John Ralls c9f3c0760c Provide fallback value for test_core_dir in case it hasn't been built yet. 2018-03-09 13:48:36 -08:00
John Ralls fbb172d096 Bug 793900 - 2.7.5: test failure: 105 - python-bindings.
unittest_support.py is in ${CMAKE_SOURCE_DIR} for a tarball build
and ${CMAKE_BINARY_DIR} for a vcs build. Look for it rather than
assuming it's in ${CMAKE_BINARY_DIR}.
2018-03-09 13:07:29 -08:00
John Ralls 474c3ae079 Make a target for the python-bindings test to set its dependencies. 2018-02-18 16:08:26 -08:00
John Ralls 74ddb671e4 Merge Chris Lam's and Aaron Laws's branch 'time64-ftw' into unstable. 2018-01-20 12:40:32 -08:00
John Ralls 91f4b19039 Convert python bindings from timespec to time64. 2018-01-20 12:35:04 -08:00