-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathenums.pxd
More file actions
108 lines (98 loc) · 3.47 KB
/
Copy pathenums.pxd
File metadata and controls
108 lines (98 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# cython: language_level=3
from libcpp.string cimport string as libcpp_string
#
# =============================================================================
# Example: Wrapping C++ Enums in Different Namespaces
# =============================================================================
#
# This file demonstrates how to wrap C++ enums that have the same name but
# exist in different namespaces (e.g., Foo::MyEnum and Foo2::MyEnum).
#
# THE PROBLEM:
# When two C++ classes/namespaces define enums with the same name, Cython
# cannot distinguish them at the module level, causing naming conflicts.
#
# THE SOLUTION:
# Use a unique Cython identifier with a C++ name string to map to the
# actual C++ enum, then use wrap-as to expose it with the desired Python name.
#
# PATTERN:
# cpdef enum class <UniqueID> "<C++::FullName>":
# # wrap-attach:
# # <ClassName>
# # wrap-as:
# # <PythonName>
#
# EXAMPLE:
# For Foo::MyEnum and Foo2::MyEnum, declare them as:
# - Foo_MyEnum "Foo::MyEnum" -> exposed as Foo.MyEnum in Python
# - Foo2_MyEnum "Foo2::MyEnum" -> exposed as Foo2.MyEnum in Python
#
# IMPORTANT:
# - Use `cpdef enum class` (not `cpdef enum`) for scoped enums
# - Scoped enums generate Python Enum classes with proper type checking
# - The wrap-attach directive attaches the enum to the specified class
# - The wrap-as directive controls the Python-visible name
#
# RESULT IN PYTHON:
# foo = Foo()
# foo.enumToInt(Foo.MyEnum.A) # Works - correct enum type
# foo.enumToInt(Foo2.MyEnum.A) # Raises AssertionError - wrong enum type
#
# =============================================================================
cdef extern from "enums.hpp":
cdef cppclass Foo:
# Method accepts Foo_MyEnum (which maps to Foo::MyEnum in C++)
int enumToInt(Foo_MyEnum e)
# Overloaded methods for testing enum-based overload resolution
libcpp_string process(Foo_MyEnum e)
libcpp_string process(Foo_MyEnum2 e)
cdef extern from "enums.hpp":
cdef cppclass Foo2:
# Foo2 has no methods, but we still wrap it to attach its enum
pass
# -----------------------------------------------------------------------------
# Enums in the "Foo" namespace
# -----------------------------------------------------------------------------
cdef extern from "enums.hpp" namespace "Foo":
# Foo::MyEnum - attached to class Foo, exposed as Foo.MyEnum
cpdef enum class Foo_MyEnum "Foo::MyEnum":
# wrap-attach:
# Foo
#
# wrap-as:
# MyEnum
#
# wrap-doc:
# Testing Enum documentation.
A
B
C
# Foo::MyEnum2 - a second enum in the same class
cpdef enum class Foo_MyEnum2 "Foo::MyEnum2":
# wrap-attach:
# Foo
#
# wrap-as:
# MyEnum2
A
B
C
# -----------------------------------------------------------------------------
# Enums in the "Foo2" namespace
# -----------------------------------------------------------------------------
cdef extern from "enums.hpp" namespace "Foo2":
# Foo2::MyEnum - same name as Foo::MyEnum but in different namespace
# Attached to Foo2 class, exposed as Foo2.MyEnum (no conflict with Foo.MyEnum)
cpdef enum class Foo2_MyEnum "Foo2::MyEnum":
# wrap-attach:
# Foo2
#
# wrap-as:
# MyEnum
#
# wrap-doc:
# This is a second enum in another namespace.
A
C
D