summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2021-07-22 11:21:19 +0200
committerStefan Behnel <stefan_ml@behnel.de>2021-07-22 11:21:19 +0200
commite583fe33074d4c5a808153b10877ce73339b8a0a (patch)
treef005f3cae61f837fdbdbcfc00d66aba5b4d41ae3
parent50cb786f5d5648b406c32036bbfce2050a8cd507 (diff)
downloadcython-e583fe33074d4c5a808153b10877ce73339b8a0a.tar.gz
Support arbitrary mappings in C++ dict-to-map conversion, not just exact dicts.
-rw-r--r--Cython/Utility/CppConvert.pyx10
-rw-r--r--tests/run/cpp_stl_conversion.pyx36
2 files changed, 33 insertions, 13 deletions
diff --git a/Cython/Utility/CppConvert.pyx b/Cython/Utility/CppConvert.pyx
index fd86b9970..35f4c50ef 100644
--- a/Cython/Utility/CppConvert.pyx
+++ b/Cython/Utility/CppConvert.pyx
@@ -199,14 +199,18 @@ cdef extern from *:
void insert(pair[T, U]&) except +
cdef cppclass vector "std::vector" [T]:
pass
+ int PY_MAJOR_VERSION
@cname("{{cname}}")
cdef map[X,Y] {{cname}}(object o) except *:
- cdef dict d = o
cdef map[X,Y] m
- for key, value in d.iteritems():
- m.insert(pair[X,Y](<X>key, <Y>value))
+ if PY_MAJOR_VERSION < 3:
+ for key, value in o.iteritems():
+ m.insert(pair[X,Y](<X>key, <Y>value))
+ else:
+ for key, value in o.items():
+ m.insert(pair[X,Y](<X>key, <Y>value))
return m
diff --git a/tests/run/cpp_stl_conversion.pyx b/tests/run/cpp_stl_conversion.pyx
index 33c19837a..07d56d68b 100644
--- a/tests/run/cpp_stl_conversion.pyx
+++ b/tests/run/cpp_stl_conversion.pyx
@@ -2,6 +2,8 @@
# tag: cpp, werror, cpp11
import sys
+from collections import defaultdict
+
from libcpp.map cimport map
from libcpp.unordered_map cimport unordered_map
from libcpp.set cimport set as cpp_set
@@ -212,22 +214,36 @@ def test_unordered_set(o):
def test_map(o):
"""
- >>> test_map({1: 1.0, 2: 0.5, 3: 0.25})
+ >>> d = {1: 1.0, 2: 0.5, 3: 0.25}
+ >>> test_map(d)
+ {1: 1.0, 2: 0.5, 3: 0.25}
+ >>> dd = defaultdict(float)
+ >>> dd.update(d)
+ >>> test_map(dd) # try with a non-dict
{1: 1.0, 2: 0.5, 3: 0.25}
"""
cdef map[int, double] m = o
return m
def test_unordered_map(o):
- """
- >>> d = test_map({1: 1.0, 2: 0.5, 3: 0.25})
- >>> sorted(d)
- [1, 2, 3]
- >>> (d[1], d[2], d[3])
- (1.0, 0.5, 0.25)
- """
- cdef unordered_map[int, double] m = o
- return m
+ """
+ >>> d = {1: 1.0, 2: 0.5, 3: 0.25}
+ >>> m = test_map(d)
+ >>> sorted(m)
+ [1, 2, 3]
+ >>> (m[1], m[2], m[3])
+ (1.0, 0.5, 0.25)
+
+ >>> dd = defaultdict(float)
+ >>> dd.update(d)
+ >>> m = test_map(dd)
+ >>> sorted(m)
+ [1, 2, 3]
+ >>> (m[1], m[2], m[3])
+ (1.0, 0.5, 0.25)
+ """
+ cdef unordered_map[int, double] m = o
+ return m
def test_nested(o):
"""