From 445ff7e6c98b9203780b434fa2dbc4dda1340e3c Mon Sep 17 00:00:00 2001 From: c-holtermann Date: Sat, 6 Apr 2019 07:51:15 +0200 Subject: [PATCH 1/8] check for argument type. Also allow int. --- bindings/python/time64.i | 51 ++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/bindings/python/time64.i b/bindings/python/time64.i index 82736186e6..e7553b5048 100644 --- a/bindings/python/time64.i +++ b/bindings/python/time64.i @@ -33,13 +33,23 @@ // require time64 as an argument %typemap(in) time64 { PyDateTime_IMPORT; - struct tm time = {PyDateTime_DATE_GET_SECOND($input), - PyDateTime_DATE_GET_MINUTE($input), - PyDateTime_DATE_GET_HOUR($input), - PyDateTime_GET_DAY($input), - PyDateTime_GET_MONTH($input) - 1, - PyDateTime_GET_YEAR($input) - 1900}; - $1 = gnc_mktime(&time); + + if (!PyDateTime_Check($input) && !PyInt_Check($input)) { + PyErr_SetString(PyExc_ValueError,"datetime or integer expected"); + return NULL; + } + + if (PyDateTime_Check($input)) { + struct tm time = {PyDateTime_DATE_GET_SECOND($input), + PyDateTime_DATE_GET_MINUTE($input), + PyDateTime_DATE_GET_HOUR($input), + PyDateTime_GET_DAY($input), + PyDateTime_GET_MONTH($input) - 1, + PyDateTime_GET_YEAR($input) - 1900}; + $1 = gnc_mktime(&time); + } else { + $1 = PyInt_AsLong($input); + } } // A typemap for converting python dates to time64 *, for functions that @@ -61,14 +71,25 @@ // Mark Jenkins %typemap(in) time64 * (time64 secs) { PyDateTime_IMPORT; - struct tm time = {PyDateTime_DATE_GET_SECOND($input), - PyDateTime_DATE_GET_MINUTE($input), - PyDateTime_DATE_GET_HOUR($input), - PyDateTime_GET_DAY($input), - PyDateTime_GET_MONTH($input) - 1, - PyDateTime_GET_YEAR($input) - 1900}; - time64 secs = gnc_mktime(&time); - $1 = &secs; + + if (!PyDateTime_Check($input) && !PyInt_Check($input)) { + PyErr_SetString(PyExc_ValueError,"datetime or integer expected"); + return NULL; + } + + if (PyDateTime_Check($input)) { + struct tm time = {PyDateTime_DATE_GET_SECOND($input), + PyDateTime_DATE_GET_MINUTE($input), + PyDateTime_DATE_GET_HOUR($input), + PyDateTime_GET_DAY($input), + PyDateTime_GET_MONTH($input) - 1, + PyDateTime_GET_YEAR($input) - 1900}; + time64 secs = gnc_mktime(&time); + $1 = &secs; + } else { + time64 secs = PyInt_AsLong($input); + $1 = &secs; + } } // A typemap for converting time64 values returned from functions to From 79decfb754fb7ff7624357e98cbbe59a66e2ee7c Mon Sep 17 00:00:00 2001 From: c-holtermann Date: Sat, 6 Apr 2019 14:08:52 +0200 Subject: [PATCH 2/8] deal with functions returning values through arguments --- bindings/python/time64.i | 43 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/bindings/python/time64.i b/bindings/python/time64.i index e7553b5048..41e552cb45 100644 --- a/bindings/python/time64.i +++ b/bindings/python/time64.i @@ -69,6 +69,12 @@ // stack. (SWIG will name the variables ts1, ts2, ts3...) // // Mark Jenkins +// +// as far as I can see all occurences of pointers to time64 are now covered +// by the named typemaps below (2019-04) +// +// Christoph Holtermann + %typemap(in) time64 * (time64 secs) { PyDateTime_IMPORT; @@ -92,8 +98,9 @@ } } -// A typemap for converting time64 values returned from functions to -// python dates. Note that we can't use Python DateTime's fromtimestamp function because it relies upon libc's localtime. Note also that while we create times with timegm we retrieve it with localtime +/* A typemap for converting time64 values returned from functions to + python dates. Note that we can't use Python DateTime's fromtimestamp function because it relies upon libc's + localtime. Note also that while we create times with timegm we retrieve it with localtime */ %typemap(out) time64 { if ($1 == INT64_MAX) { $result = Py_None; @@ -106,3 +113,35 @@ t.tm_sec, 0); } } + +// functions using a pointer to time64 to return data +// these are named typemaps focussing for +// +// gboolean qof_query_date_predicate_get_date (const QofQueryPredData *pd, time64 *date) +// gboolean xaccAccountGetReconcileLastDate (const Account *acc, time64 *last_date) +// gboolean xaccAccountGetReconcilePostponeDate (const Account *acc, time64 *postpone_date) +// +// python functions return a list where the first item is the boolean return value and +// the second item is a datetime object. This could be reduced to only returning a date or +// null +// +// the modifiable argument is omitted in python function call + +%typemap(in, numinputs=0) time64 *date (time64 secs) { + $1 = &secs; +} + +%typemap(argout) time64 *date (time64 secs) { + PyDateTime_IMPORT; + PyObject *tp; + struct tm t; + gnc_localtime_r($1, &t); + tp = PyDateTime_FromDateAndTime(t.tm_year + 1900, t.tm_mon + 1, + t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, 0); + + $result = SWIG_Python_AppendOutput($result, tp); +} + +%apply time64 *date { time64 *last_date }; +%apply time64 *date { time64 *postpone_date }; From dafdd702e6bfffee5fe75f973f8a67320586c7ff Mon Sep 17 00:00:00 2001 From: c-holtermann Date: Sat, 6 Apr 2019 14:09:10 +0200 Subject: [PATCH 3/8] additional author --- bindings/python/time64.i | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/python/time64.i b/bindings/python/time64.i index 41e552cb45..88d3453477 100644 --- a/bindings/python/time64.i +++ b/bindings/python/time64.i @@ -27,6 +27,7 @@ @brief SWIG interface file for type translation of time64 types @author Mark Jenkins, ParIT Worker Co-operative @author Jeff Green, ParIT Worker Co-operative + @author Christoph Holtermann, mail@c-holtermann.net - modifications 2019-04 @ingroup python_bindings */ // A typemap for converting python dates to time64 in functions that From 8ba5e552d92a9c745ba1295d76b3bcfd3408a485 Mon Sep 17 00:00:00 2001 From: c-holtermann Date: Sat, 6 Apr 2019 14:50:29 +0200 Subject: [PATCH 4/8] return None object if return value is FALSE --- bindings/python/time64.i | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/bindings/python/time64.i b/bindings/python/time64.i index 88d3453477..dfedfa6354 100644 --- a/bindings/python/time64.i +++ b/bindings/python/time64.i @@ -136,12 +136,17 @@ PyDateTime_IMPORT; PyObject *tp; struct tm t; - gnc_localtime_r($1, &t); - tp = PyDateTime_FromDateAndTime(t.tm_year + 1900, t.tm_mon + 1, - t.tm_mday, t.tm_hour, t.tm_min, - t.tm_sec, 0); - $result = SWIG_Python_AppendOutput($result, tp); + // directly access return value (result) of function + // only return datetime if TRUE + if(result) { + gnc_localtime_r($1, &t); + tp = PyDateTime_FromDateAndTime(t.tm_year + 1900, t.tm_mon + 1, + t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, 0); + + $result = SWIG_Python_AppendOutput($result, tp); + } else $result = SWIG_Python_AppendOutput($result, Py_None); } %apply time64 *date { time64 *last_date }; From 3884e6abf549ad5c6c8d09604a493d3f9ff88371 Mon Sep 17 00:00:00 2001 From: c-holtermann Date: Sat, 6 Apr 2019 16:09:01 +0200 Subject: [PATCH 5/8] unobfuscate get_date method name --- bindings/python/gnucash_core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bindings/python/gnucash_core.py b/bindings/python/gnucash_core.py index b268503ebb..38415abe8f 100644 --- a/bindings/python/gnucash_core.py +++ b/bindings/python/gnucash_core.py @@ -812,7 +812,8 @@ class QueryDatePredicate(GnuCashCoreClass): pass QueryDatePredicate.add_constructor_and_methods_with_prefix( - 'qof_query_', 'date_predicate') + 'qof_query_', 'date_predicate', exclude=["qof_query_date_predicate_get_date"]) +QueryDatePredicate.add_method('qof_query_date_predicate_get_date', 'get_date') class QueryGuidPredicate(GnuCashCoreClass): pass From db9e98a812daf6d293f29c6ed07a50dd28b8f70e Mon Sep 17 00:00:00 2001 From: c-holtermann Date: Sat, 6 Apr 2019 16:10:04 +0200 Subject: [PATCH 6/8] also allow datetime.date Initialisation of some business objects has been done with datetime.date.today() and it is also mentioned as a possibility in the source doc. So leave it possible. --- bindings/python/time64.i | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/python/time64.i b/bindings/python/time64.i index dfedfa6354..1840b87c60 100644 --- a/bindings/python/time64.i +++ b/bindings/python/time64.i @@ -35,8 +35,8 @@ %typemap(in) time64 { PyDateTime_IMPORT; - if (!PyDateTime_Check($input) && !PyInt_Check($input)) { - PyErr_SetString(PyExc_ValueError,"datetime or integer expected"); + if (!PyDate_Check($input) && !PyDateTime_Check($input) && !PyInt_Check($input)) { + PyErr_SetString(PyExc_ValueError,"date, datetime or integer expected"); return NULL; } @@ -79,8 +79,8 @@ %typemap(in) time64 * (time64 secs) { PyDateTime_IMPORT; - if (!PyDateTime_Check($input) && !PyInt_Check($input)) { - PyErr_SetString(PyExc_ValueError,"datetime or integer expected"); + if (!PyDate_Check($input) && !PyDateTime_Check($input) && !PyInt_Check($input)) { + PyErr_SetString(PyExc_ValueError,"date, datetime or integer expected"); return NULL; } From 18a26884197cc72551a58c77c88f7355bebe01eb Mon Sep 17 00:00:00 2001 From: c-holtermann Date: Sat, 6 Apr 2019 16:17:58 +0200 Subject: [PATCH 7/8] typo --- bindings/python/gnucash_business.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/gnucash_business.py b/bindings/python/gnucash_business.py index 53b8e1b345..b4583377db 100644 --- a/bindings/python/gnucash_business.py +++ b/bindings/python/gnucash_business.py @@ -143,7 +143,7 @@ class TaxTableEntry(GnuCashCoreClass): class Invoice(GnuCashCoreClass): def __init__(self, book=None, id=None, currency=None, owner=None, date_opened=None, instance=None): - """Invoice Contstructor + """Invoice Constructor You must provide a book, id, currency and owner (Customer, Job, Employee, Vendor) or an existing swig proxy object From 0c028669642ae4a5937bbb2f3c4344280eec283c Mon Sep 17 00:00:00 2001 From: c-holtermann Date: Sat, 6 Apr 2019 17:13:41 +0200 Subject: [PATCH 8/8] PyDate_Check works for date and datetime --- bindings/python/time64.i | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/python/time64.i b/bindings/python/time64.i index 1840b87c60..295a99a797 100644 --- a/bindings/python/time64.i +++ b/bindings/python/time64.i @@ -35,12 +35,12 @@ %typemap(in) time64 { PyDateTime_IMPORT; - if (!PyDate_Check($input) && !PyDateTime_Check($input) && !PyInt_Check($input)) { + if (!PyDate_Check($input) && !PyInt_Check($input)) { PyErr_SetString(PyExc_ValueError,"date, datetime or integer expected"); return NULL; } - if (PyDateTime_Check($input)) { + if (PyDate_Check($input)) { struct tm time = {PyDateTime_DATE_GET_SECOND($input), PyDateTime_DATE_GET_MINUTE($input), PyDateTime_DATE_GET_HOUR($input), @@ -79,12 +79,12 @@ %typemap(in) time64 * (time64 secs) { PyDateTime_IMPORT; - if (!PyDate_Check($input) && !PyDateTime_Check($input) && !PyInt_Check($input)) { + if (!PyDate_Check($input) && !PyInt_Check($input)) { PyErr_SetString(PyExc_ValueError,"date, datetime or integer expected"); return NULL; } - if (PyDateTime_Check($input)) { + if (PyDate_Check($input)) { struct tm time = {PyDateTime_DATE_GET_SECOND($input), PyDateTime_DATE_GET_MINUTE($input), PyDateTime_DATE_GET_HOUR($input),