[neon/forks/sip6/Neon/release] /: New upstream version 6.13.1

Dmitry Shachnev null at kde.org
Wed Dec 3 06:39:48 GMT 2025


Git commit c0a68b3dc7f250ea56a9aa9f49fc76402062eac0 by Dmitry Shachnev.
Committed on 10/10/2025 at 20:31.
Pushed by carlosdem into branch 'Neon/release'.

New upstream version 6.13.1

M  +3    -3    .git_archival.txt
M  +1    -1    docs/conf.py
M  +8    -0    docs/releases.md
M  +0    -9    sipbuild/generator/resolver/resolver.py
M  +7    -1    sipbuild/generator/utils.py
A  +172  -0    test/template_typedef/template_typedef_module.sip
A  +19   -0    test/template_typedef/test_template_typedef.py

https://invent.kde.org/neon/forks/sip6/-/commit/c0a68b3dc7f250ea56a9aa9f49fc76402062eac0

diff --git a/.git_archival.txt b/.git_archival.txt
index 977f84d..972908a 100644
--- a/.git_archival.txt
+++ b/.git_archival.txt
@@ -1,3 +1,3 @@
-node: c4cab8396437b405b79d50565e87b37bffb046e0
-node-date: 2025-10-07T15:07:59+01:00
-describe-name: 6.13.0
+node: bc5fb1968bf3b6177fda61308f0a4ed2e58472c2
+node-date: 2025-10-10T16:26:04+01:00
+describe-name: 6.13.1
diff --git a/docs/conf.py b/docs/conf.py
index 71583b4..90d7345 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -13,7 +13,7 @@ project = 'sip'
 copyright = '{0} Phil Thompson <phil at riverbankcomputing.com>'.format(
         date.today().year)
 author = 'Phil Thompson'
-version = 'v6.13.0'
+version = 'v6.13.1'
 
 
 # -- General configuration ---------------------------------------------------
diff --git a/docs/releases.md b/docs/releases.md
index 3ab6dcb..40f3729 100644
--- a/docs/releases.md
+++ b/docs/releases.md
@@ -1,5 +1,13 @@
 # Release Notes
 
+## v6.13.1
+
+### Bug fixes
+
+Fixed a regression in v6.13.0 in the handling of mapped types for C++
+templates with `typedef`ed arguments.
+
+
 ## v6.13.0
 
 ### `/ExportDerivedLocally/` class annotation
diff --git a/sipbuild/generator/resolver/resolver.py b/sipbuild/generator/resolver/resolver.py
index 4a6d067..9dbc2e9 100644
--- a/sipbuild/generator/resolver/resolver.py
+++ b/sipbuild/generator/resolver/resolver.py
@@ -1783,15 +1783,6 @@ def _resolve_type(spec, mod, scope, type, error_log, allow_defined=False):
 
             return
 
-    # Do a lightweight lookup of any template arguments that will resolve
-    # typedefs.
-    if type.type is ArgumentType.TEMPLATE:
-        for arg in type.definition.types.args:
-            if arg.type is ArgumentType.DEFINED:
-                _name_lookup(spec, mod, arg.definition, arg)
-                if arg.type is ArgumentType.NONE:
-                    arg.type = ArgumentType.DEFINED
-
     # See if the type refers to an instantiated template.
     _resolve_instantiated_class_template(spec, type)
 
diff --git a/sipbuild/generator/utils.py b/sipbuild/generator/utils.py
index 1b746c4..5bebc5e 100644
--- a/sipbuild/generator/utils.py
+++ b/sipbuild/generator/utils.py
@@ -355,12 +355,18 @@ def same_base_type(type1, type2):
 
     # The types must be the same.
     if type1.type is not type2.type:
+        # Compare original typedef names if appropriate.
+        if type1.original_typedef is not None and type2.type is ArgumentType.DEFINED:
+            return type1.original_typedef.fq_cpp_name.matches(type2.definition)
+
+        if type1.type is ArgumentType.DEFINED and type2.original_typedef is not None:
+            return type2.original_typedef.fq_cpp_name.matches(type1.definition)
+
         # If we are comparing a template with those that have already been used
         # to instantiate a class or mapped type then we need to compare with
         # the class or mapped type name.
 
         if type1.type is ArgumentType.CLASS and type2.type is ArgumentType.DEFINED:
-
             return type1.definition.iface_file.fq_cpp_name.matches(type2.definition)
 
         if type1.type is ArgumentType.DEFINED and type2.type is ArgumentType.CLASS:
diff --git a/test/template_typedef/template_typedef_module.sip b/test/template_typedef/template_typedef_module.sip
new file mode 100644
index 0000000..661c725
--- /dev/null
+++ b/test/template_typedef/template_typedef_module.sip
@@ -0,0 +1,172 @@
+// The SIP implementation of the typedefs_module test module.
+
+
+%Module(name=template_typedef_module)
+
+
+%ExportedHeaderCode
+// The need for this, ie. to resolve the type as a typedef, is a SIP bug.
+#define getSipType(sipTypename) (sipResolveTypedef(sipTypename) ? sipFindType(sipResolveTypedef(sipTypename)) : sipFindType(sipTypename))
+%End
+
+
+template<TYPE>
+%MappedType std::vector<TYPE> /TypeHint="List[TYPE]"/ {
+%TypeHeaderCode
+#include <vector>
+%End
+
+%ConvertFromTypeCode
+    //const sipTypeDef *kpTypeDef = sipFindType("TYPE");
+    const sipTypeDef *kpTypeDef = getSipType("TYPE");
+
+    if (!kpTypeDef) {
+        return NULL;
+    }
+
+    // Create the Python list of the correct length.
+    PyObject *l;
+
+    if ((l = PyList_New(sipCpp->size())) == NULL) {
+        return NULL;
+    }
+
+    // Go through each element in the C++ instance and convert it to a SIP
+    // wrapper.
+    for (size_t i = 0; i < sipCpp->size(); ++i) {
+        TYPE *cpp = new TYPE(sipCpp->at(i));
+        PyObject *pobj;
+
+        // Get the Python wrapper for the Type instance, creating a new one if
+        // necessary, and handle any ownership transfer.
+        if ((pobj = sipConvertFromNewType(cpp, kpTypeDef, sipTransferObj)) == NULL) {
+            // There was an error so garbage collect the Python list.
+            Py_XDECREF(l);
+            return NULL;
+        }
+
+        // Add the wrapper to the list.
+        PyList_SET_ITEM(l, i, pobj);
+    }
+
+    // Return the Python list.
+    return l;
+%End
+
+%ConvertToTypeCode
+    //const sipTypeDef *kpTypeDef = sipFindType("TYPE");
+    const sipTypeDef *kpTypeDef = getSipType("TYPE");
+
+    if (!kpTypeDef) {
+        return 0;
+    }
+
+    // Check if type is compatible
+    if (sipIsErr == NULL) {
+        return PyList_Check(sipPy);
+    }
+
+    // Convert Python list of TYPE to  std::vector<TYPE>
+    std::vector<TYPE> *v = new std::vector<TYPE>();
+    v->reserve(PyList_GET_SIZE(sipPy));
+
+    for (Py_ssize_t i = 0; i < PyList_GET_SIZE(sipPy); ++i) {
+        int state;
+        TYPE *p = static_cast<TYPE *>(sipConvertToType(
+                PyList_GET_ITEM(sipPy, i), kpTypeDef, sipTransferObj,
+                SIP_NOT_NONE, &state, sipIsErr));
+
+        if (*sipIsErr) {
+            sipReleaseType(p, kpTypeDef, state);
+            delete v;
+            return 0;
+        }
+
+        v->push_back(*p);
+        sipReleaseType(p, kpTypeDef, state);
+    }
+
+    *sipCppPtr = v;
+
+    return sipGetState(sipTransferObj);
+%End
+};
+
+
+%MappedType std::vector<int> /TypeHint="List[int]"/ {
+%TypeHeaderCode
+#include <vector>
+%End
+
+%ConvertFromTypeCode
+    PyObject *l;
+
+    // Create the Python list of the correct length.
+    if ((l = PyList_New(sipCpp->size())) == NULL) {
+        return NULL;
+    }
+
+    // Go through each element in the C++ instance and convert it to a wrapped
+    // object.
+    for (size_t i = 0; i < sipCpp->size(); ++i) {
+        // Add the wrapper to the list.
+        PyList_SET_ITEM(l, i, PyLong_FromLong(sipCpp->at(i)));
+    }
+
+    // Return the Python list.
+    return l;
+%End
+
+%ConvertToTypeCode
+    // Check if type is compatible
+    if (sipIsErr == NULL) {
+        return PyList_Check(sipPy);
+    }
+
+    // Convert Python list of integers to a std::vector<int>
+    std::vector<int> *v = new std::vector<int>();
+    v->reserve(PyList_GET_SIZE(sipPy));
+
+    for (Py_ssize_t i = 0; i < PyList_GET_SIZE(sipPy); ++i) {
+        v->push_back(int(PyLong_AsLong(PyList_GET_ITEM(sipPy, i))));
+    }
+
+    *sipCppPtr = v;
+
+    return sipGetState(sipTransferObj);
+%End
+};
+
+
+%ModuleHeaderCode
+#include <vector>
+std::vector<int> incrementVectorInt(const std::vector<int> &v);
+std::vector<std::vector<int> > incrementVectorVectorInt(
+        const std::vector<std::vector<int> > &v);
+typedef std::vector<int> VecInt;
+%End
+
+
+%ModuleCode
+std::vector<int> incrementVectorInt(const std::vector<int> &v) {
+    std::vector<int> ret;
+    for (std::vector<int>::const_iterator i = v.cbegin(); i != v.cend(); ++i) {
+        ret.push_back(*i+1);
+    }
+    return ret;
+}
+
+std::vector<std::vector<int> > incrementVectorVectorInt(
+        const std::vector<std::vector<int> > &v) {
+    std::vector<std::vector<int> > ret;
+    for (std::vector<std::vector<int> >::const_iterator i = v.cbegin(); i != v.cend(); ++i) {
+        ret.push_back(incrementVectorInt(*i));
+    }
+    return ret;
+}
+%End
+
+
+typedef std::vector<int> VecInt;
+std::vector<int> incrementVectorInt(const std::vector<int> &v);
+std::vector<VecInt> incrementVectorVectorInt(const std::vector<VecInt> &v);
diff --git a/test/template_typedef/test_template_typedef.py b/test/template_typedef/test_template_typedef.py
new file mode 100644
index 0000000..ccc5d30
--- /dev/null
+++ b/test/template_typedef/test_template_typedef.py
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: BSD-2-Clause
+
+# Copyright (c) 2025 Phil Thompson <phil at riverbankcomputing.com>
+
+
+from utils import SIPTestCase
+
+
+class TypedefsTestCase(SIPTestCase):
+    """ Test the support for template typedef. """
+
+    def test_ModuleTemplateTypedef(self):
+        """ Test the support for template typedef. """
+
+        import template_typedef_module as ttdm
+
+        self.assertEqual(ttdm.incrementVectorInt([1, 2, 3]), [2, 3, 4])
+        self.assertEqual(ttdm.incrementVectorVectorInt([[1, 2, 3], [4, 5, 6]]),
+                [[2, 3, 4], [5, 6, 7]])



More information about the Neon-commits mailing list