changeset 61:c5a69c454963

- allow use of 'None' with 'Z' - bumped version to 1.4 (be in sync current dyncall version)
author Tassilo Philipp
date Mon, 03 Apr 2023 19:06:07 +0200
parents 8e905c0798c7
children 4a9f6c7c09c1
files python/pydc/README.txt python/pydc/pydc.c python/pydc/setup.py python/pydc/test/types_test.py
diffstat 4 files changed, 18 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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++]);
 			}
--- 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'
--- 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