# HG changeset patch # User Tassilo Philipp # Date 1680541567 -7200 # Node ID c5a69c454963244de1853edb61460f033c457ff7 # Parent 8e905c0798c70944ec6d624bc096c56451cd91ce - allow use of 'None' with 'Z' - bumped version to 1.4 (be in sync current dyncall version) diff -r 8e905c0798c7 -r c5a69c454963 python/pydc/README.txt --- a/python/pydc/README.txt Wed Aug 03 15:38:07 2022 +0200 +++ b/python/pydc/README.txt Mon Apr 03 19:06:07 2023 +0200 @@ -1,6 +1,6 @@ dyncall python bindings Copyright 2007-2016 Daniel Adler - 2018-2022 Tassilo Philipp + 2018-2023 Tassilo Philipp Dec 4, 2007: initial Mar 22, 2016: update to dyncall 0.9, includes breaking sig char changes @@ -21,9 +21,9 @@ Aug 3, 2022: added p2Z() helper function (e.g. helpful when working with string 'p'ointers that eventually need to be free()'d, as no implicit 'Z' conversion is taking place) - - - +Apr 3, 2023: allowing 'None' for 'Z' params + + BUILD/INSTALLATION @@ -103,6 +103,7 @@ | unicode (PyUnicode) ! | - | const char* (UTF-8 for unicode) | str (PyString) | str (PyUnicode) | - | bytes (PyBytes) ! | const char* (UTF-8 for unicode) | str (PyString) | str (PyUnicode) | bytearray (PyByteArray) ! | bytearray (PyByteArray) ! | const char* (UTF-8 for unicode) | str (PyString) | str (PyUnicode) + | None (Py_None) | None (Py_None) | const char* (always NULL) | None (Py_None) | None (Py_None) Annotations: # converted to 1 if True and 0 otherwise diff -r 8e905c0798c7 -r c5a69c454963 python/pydc/pydc.c --- a/python/pydc/pydc.c Wed Aug 03 15:38:07 2022 +0200 +++ b/python/pydc/pydc.c Mon Apr 03 19:06:07 2023 +0200 @@ -4,7 +4,7 @@ ** ** python extension package in C ** Copyright 2007-2016 Daniel Adler - ** 2018-2020 Tassilo Philipp + ** 2018-2023 Tassilo Philipp ** ** See README.txt for details (about changes, how to use, etc.). ** @@ -437,7 +437,6 @@ { PyObject* bo = NULL; const char* p; - size_t s; if ( PyUnicode_Check(po) ) { #if defined(PYUNICODE_CACHES_UTF8) @@ -451,16 +450,22 @@ p = DcPyString_AsString(po); else if ( PyByteArray_Check(po) ) p = (DCpointer) PyByteArray_AsString(po); // adds an extra '\0', but that's ok //@@@ not sure if allowed to modify + else if ( po == Py_None ) + p = NULL; else return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a str", pos ); if(n_str_aux >= NUM_AUX_STRS) return PyErr_Format( PyExc_RuntimeError, "too many arguments (implementation limit of %d new UTF-8 string references reached) - abort", n_str_aux ); - // p points in every case to a buffer that shouldn't be modified, so pass a copy to dyncall (cleaned up after call) - s = strlen(p)+1; - str_aux[n_str_aux] = malloc(s); - strncpy(str_aux[n_str_aux], p, s); + if(!p) + str_aux[n_str_aux] = NULL; + else { + // p points in every case to a buffer that shouldn't be modified, so pass a copy to dyncall (cleaned up after call) + size_t s = strlen(p)+1; + str_aux[n_str_aux] = malloc(s); + strncpy(str_aux[n_str_aux], p, s); + } Py_XDECREF(bo); dcArgPointer(gpCall, (DCpointer)str_aux[n_str_aux++]); } diff -r 8e905c0798c7 -r c5a69c454963 python/pydc/setup.py --- a/python/pydc/setup.py Wed Aug 03 15:38:07 2022 +0200 +++ b/python/pydc/setup.py Mon Apr 03 19:06:07 2023 +0200 @@ -7,7 +7,7 @@ setup( name = 'pydc' -, version = '1.2.6' +, version = '1.4.0' , author = 'Daniel Adler, Tassilo Philipp' , author_email = 'dadler@dyncall.org, tphilip@dyncall.org' , maintainer = 'Daniel Adler, Tassilo Philipp' diff -r 8e905c0798c7 -r c5a69c454963 python/pydc/test/types_test.py --- a/python/pydc/test/types_test.py Wed Aug 03 15:38:07 2022 +0200 +++ b/python/pydc/test/types_test.py Mon Apr 03 19:06:07 2023 +0200 @@ -142,6 +142,7 @@ t(l, "Z)Z", "const char*", "ccp_plus_one", "(const char*)", '"X_unicode" => "_unicode"', i=( u'X_unicode',), r=u'_unicode') # string object (unicode in Python 2) t(l, "Z)Z", "const char*", "ccp_plus_one", "(const char*)", '"1lessbyte" => "lessbyte"', i=( b'1lessbyte',), r= 'lessbyte') # bytes object t(l, "Z)Z", "const char*", "ccp_plus_one", "(const char*)", ' "xY" => "Y"', i=(bytearray(b'xY'),), r= 'Y') # bytearray object +t(l, "Z)p", "const char*", "ccp_plus_one", "(const char*)", ' NULL => NULL+1=1', i=( None,), r=1) # NULL, adding one will result in 0x1 t(l, "p)Z", "const char*", "ccp_plus_one", "(const char*)", ' "xY" => "Y"', i=(bytearray(b'xY'),), r='Y') # bytearray object t(l, "p)p", "const char*", "ccp_plus_one", "(const char*)", ' "xY" => p+1 (~ odd addr)', i=(bytearray(b'xY'),), r=lambda i: type(i) is int and (i%2)==1) # bytearray object