summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-Hsiang Cheng <88014292+garychia@users.noreply.github.com>2023-03-05 19:53:15 +0800
committerGitHub <noreply@github.com>2023-03-05 11:53:15 +0000
commit85945aae8ad42440fc3bf5f7c9be64a0a68b2952 (patch)
tree139137539d16e487eb8acd711060d4cda82e33c4
parente552cfb779dd69d784823d070a8aaf29547796d6 (diff)
downloadcython-85945aae8ad42440fc3bf5f7c9be64a0a68b2952.tar.gz
Allow nested C++ names after a module name (#5229)
Allow code like the following to compile: cimport m def my_func(): cdef m.CppClass.NestedClass c where m is a module, CppClass is a C++ class and NestedClass is a nested class inside CppClass.
-rw-r--r--Cython/Compiler/Nodes.py2
-rw-r--r--tests/run/cpp_nested_classes.pyx27
-rw-r--r--tests/run/cpp_nested_names.pxd17
-rw-r--r--tests/run/cpp_nested_names_helper.h20
4 files changed, 66 insertions, 0 deletions
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
index 9c320cafa..3219768b7 100644
--- a/Cython/Compiler/Nodes.py
+++ b/Cython/Compiler/Nodes.py
@@ -1097,6 +1097,8 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
entry.is_type and entry.type.is_cpp_class
):
scope = entry.type.scope
+ elif entry and entry.as_module:
+ scope = entry.as_module
else:
scope = None
break
diff --git a/tests/run/cpp_nested_classes.pyx b/tests/run/cpp_nested_classes.pyx
index 8877c0440..50a453901 100644
--- a/tests/run/cpp_nested_classes.pyx
+++ b/tests/run/cpp_nested_classes.pyx
@@ -185,3 +185,30 @@ def test_nested_sub_struct(x):
assert s.int_value == x
s.typed_value = x
return s.typed_value
+
+cimport cpp_nested_names
+cimport libcpp.string
+from cython.operator cimport dereference as deref, preincrement as inc
+
+def test_nested_names():
+ """
+ >>> test_nested_names()
+ Nested
+ NestedNested
+ C
+ y
+ t
+ h
+ o
+ n
+ """
+ cdef cpp_nested_names.Outer.Nested n = cpp_nested_names.Outer.get()
+ cdef cpp_nested_names.Outer.Nested.NestedNested nn = n.get()
+ print(n.get_str().decode('ascii'))
+ print(nn.get_str().decode('ascii'))
+
+ cdef libcpp.string.string s = "Cython"
+ cdef libcpp.string.string.iterator i = s.begin()
+ while i != s.end():
+ print(chr(deref(i)))
+ inc(i)
diff --git a/tests/run/cpp_nested_names.pxd b/tests/run/cpp_nested_names.pxd
new file mode 100644
index 000000000..04b5f8f97
--- /dev/null
+++ b/tests/run/cpp_nested_names.pxd
@@ -0,0 +1,17 @@
+# cython: language_level=3
+
+from libcpp.string cimport string
+
+cdef extern from "cpp_nested_names_helper.h":
+ cdef cppclass Outer:
+ cppclass Nested:
+ cppclass NestedNested:
+ string get_str()
+
+ string get_str()
+
+ @staticmethod
+ NestedNested get()
+
+ @staticmethod
+ Nested get()
diff --git a/tests/run/cpp_nested_names_helper.h b/tests/run/cpp_nested_names_helper.h
new file mode 100644
index 000000000..02aae485a
--- /dev/null
+++ b/tests/run/cpp_nested_names_helper.h
@@ -0,0 +1,20 @@
+#ifndef CPP_NESTED_NAMES_HELPER_H
+#define CPP_NESTED_NAMES_HELPER_H
+
+#include <string>
+
+struct Outer {
+ struct Nested {
+ struct NestedNested {
+ std::string get_str() { return "NestedNested"; }
+ };
+
+ std::string get_str() { return "Nested"; }
+
+ static NestedNested get() { return NestedNested(); }
+ };
+
+ static Nested get() { return Outer::Nested(); }
+};
+
+#endif