@@ -2075,6 +2075,7 @@ def create_default_cimports(self):
20752075 |from libcpp.string cimport string as libcpp_utf8_output_string
20762076 |from libcpp.set cimport set as libcpp_set
20772077 |from libcpp.vector cimport vector as libcpp_vector
2078+ |from libcpp.vector cimport vector as libcpp_vector_as_np
20782079 |from libcpp.pair cimport pair as libcpp_pair
20792080 |from libcpp.map cimport map as libcpp_map
20802081 |from libcpp.unordered_map cimport unordered_map as libcpp_unordered_map
@@ -2084,7 +2085,7 @@ def create_default_cimports(self):
20842085 |from libcpp.optional cimport optional as libcpp_optional
20852086 |from libcpp.string_view cimport string_view as libcpp_string_view
20862087 |from libcpp cimport bool
2087- |from libc.string cimport const_char
2088+ |from libc.string cimport const_char, memcpy
20882089 |from cython.operator cimport dereference as deref,
20892090 + preincrement as inc, address as address
20902091 """
@@ -2119,6 +2120,7 @@ def create_default_cimports(self):
21192120 |import numpy as np
21202121 |cimport numpy as numpy
21212122 |import numpy as numpy
2123+ |from cpython.ref cimport Py_INCREF
21222124 """
21232125 )
21242126
@@ -2131,7 +2133,50 @@ def create_std_cimports(self):
21312133 code .add (stmt )
21322134
21332135 self .top_level_code .append (code )
2136+
2137+ # If numpy is enabled, inline the ArrayWrapper/ArrayView classes
2138+ if self .include_numpy :
2139+ self .inline_array_wrappers ()
2140+
21342141 return code
2142+
2143+ def inline_array_wrappers (self ):
2144+ """Inline ArrayWrapper class definitions for buffer protocol support.
2145+
2146+ ArrayWrapper classes are used for value returns where data is already copied.
2147+ For reference returns, Cython memory views are used instead (no wrapper needed).
2148+ """
2149+ # Read the combined ArrayWrappers.pyx file (which has attributes already inline)
2150+ autowrap_dir = os .path .dirname (os .path .abspath (__file__ ))
2151+ array_wrappers_pyx = os .path .join (autowrap_dir , "data_files" , "autowrap" , "ArrayWrappers.pyx" )
2152+
2153+ if not os .path .exists (array_wrappers_pyx ):
2154+ L .warning ("ArrayWrappers.pyx not found, skipping inline array wrappers" )
2155+ return
2156+
2157+ with open (array_wrappers_pyx , 'r' ) as f :
2158+ pyx_content = f .read ()
2159+
2160+ # Remove the first few lines (cython directives and module docstring)
2161+ # Keep everything from the first import onward
2162+ lines = pyx_content .split ('\n ' )
2163+ start_idx = 0
2164+ for i , line in enumerate (lines ):
2165+ if line .strip ().startswith ('from cpython.buffer' ):
2166+ start_idx = i
2167+ break
2168+
2169+ wrapper_code_str = '\n ' .join (lines [start_idx :])
2170+
2171+ code = Code ()
2172+ code .add ("""
2173+ |# Inlined ArrayWrapper classes for buffer protocol support (value returns)
2174+ |# Reference returns use Cython memory views instead
2175+ """ )
2176+ # Add the wrapper code directly
2177+ code .add (wrapper_code_str )
2178+
2179+ self .top_level_code .append (code )
21352180
21362181 def create_includes (self ):
21372182 code = Code ()
0 commit comments