@@ -17,7 +17,8 @@ def build_python(cpython_path, version):
17
17
print ("Compiling python %s from repo at %s" % (version , cpython_path ))
18
18
install_path = os .path .abspath (os .path .join (cpython_path , version ))
19
19
20
- ret = os .system (f"""
20
+ ret = os .system (
21
+ f"""
21
22
cd { cpython_path }
22
23
git checkout { version }
23
24
@@ -27,7 +28,8 @@ def build_python(cpython_path, version):
27
28
../configure prefix={ install_path }
28
29
make
29
30
make install
30
- """ )
31
+ """
32
+ )
31
33
if ret :
32
34
return ret
33
35
@@ -57,8 +59,9 @@ def calculate_pyruntime_offsets(cpython_path, version, configure=False):
57
59
size_t interp_head = offsetof(_PyRuntimeState, interpreters.head);
58
60
printf("pub static INTERP_HEAD_OFFSET: usize = %i;\n", interp_head);
59
61
60
- size_t tstate_current = offsetof(_PyRuntimeState, gilstate.tstate_current);
61
- printf("pub static TSTATE_CURRENT: usize = %i;\n", tstate_current);
62
+ // tstate_current has been replaced by a thread-local variable in python 3.12
63
+ // size_t tstate_current = offsetof(_PyRuntimeState, gilstate.tstate_current);
64
+ // printf("pub static TSTATE_CURRENT: usize = %i;\n", tstate_current);
62
65
}
63
66
"""
64
67
@@ -88,7 +91,7 @@ def calculate_pyruntime_offsets(cpython_path, version, configure=False):
88
91
else :
89
92
ret = os .system (f"""gcc { source_filename } -I { cpython_path } -I { cpython_path } /Include -o { exe } """ )
90
93
if ret :
91
- print ("Failed to compile" "" )
94
+ print ("Failed to compile" )
92
95
return ret
93
96
94
97
ret = os .system (exe )
@@ -100,19 +103,22 @@ def calculate_pyruntime_offsets(cpython_path, version, configure=False):
100
103
def extract_bindings (cpython_path , version , configure = False ):
101
104
print ("Generating bindings for python %s from repo at %s" % (version , cpython_path ))
102
105
103
- ret = os .system (f"""
106
+ ret = os .system (
107
+ f"""
104
108
cd { cpython_path }
105
109
git checkout { version }
106
110
107
111
# need to run configure on the current branch to generate pyconfig.h sometimes
108
112
{ ("./configure prefix=" + os .path .abspath (os .path .join (cpython_path , version ))) if configure else "" }
109
113
110
- cat Include/Python.h > bindgen_input.h
111
- cat Include/frameobject.h > > bindgen_input.h
114
+
115
+ echo "// autogenerated by generate_bindings.py " > bindgen_input.h
112
116
echo '#define Py_BUILD_CORE 1\n ' >> bindgen_input.h
113
- cat Include/internal/pycore_pystate.h >> bindgen_input.h
117
+ cat Include/Python.h >> bindgen_input.h
118
+ echo '#undef HAVE_STD_ATOMIC' >> bindgen_input.h
119
+ cat Include/frameobject.h >> bindgen_input.h
114
120
cat Include/internal/pycore_interp.h >> bindgen_input.h
115
- cat Include/internal/pycore_frame .h >> bindgen_input.h
121
+ cat Include/internal/pycore_dict .h >> bindgen_input.h
116
122
117
123
bindgen bindgen_input.h -o bindgen_output.rs \
118
124
--with-derive-default \
@@ -132,13 +138,12 @@ def extract_bindings(cpython_path, version, configure=False):
132
138
--whitelist-type PyFloatObject \
133
139
--whitelist-type PyDictObject \
134
140
--whitelist-type PyDictKeysObject \
135
- --whitelist-type PyDictKeyEntry \
136
- --whitelist-type PyDictUnicodeEntry \
137
141
--whitelist-type PyObject \
138
142
--whitelist-type PyTypeObject \
139
143
--whitelist-type PyHeapTypeObject \
140
144
-- -I . -I ./Include -I ./Include/internal
141
- """ )
145
+ """
146
+ )
142
147
if ret :
143
148
return ret
144
149
@@ -152,36 +157,40 @@ def extract_bindings(cpython_path, version, configure=False):
152
157
o .write ("#![allow(clippy::useless_transmute)]\n " )
153
158
o .write ("#![allow(clippy::default_trait_access)]\n " )
154
159
o .write ("#![allow(clippy::cast_lossless)]\n " )
155
- o .write ("#![allow(clippy::trivially_copy_pass_by_ref)]\n \n " )
156
- o .write ("#![allow(clippy::upper_case_acronyms)]\n \n " )
160
+ o .write ("#![allow(clippy::trivially_copy_pass_by_ref)]\n " )
161
+ o .write ("#![allow(clippy::upper_case_acronyms)]\n " )
162
+ o .write ("#![allow(clippy::too_many_arguments)]\n \n " )
163
+
157
164
o .write (open (os .path .join (cpython_path , "bindgen_output.rs" )).read ())
158
165
159
166
160
167
if __name__ == "__main__" :
161
-
162
168
if sys .platform .startswith ("win" ):
163
169
default_cpython_path = os .path .join (os .getenv ("userprofile" ), "code" , "cpython" )
164
170
else :
165
171
default_cpython_path = os .path .join (os .getenv ("HOME" ), "code" , "cpython" )
166
172
167
- parser = argparse .ArgumentParser (description = "runs bindgen on cpython version" ,
168
- formatter_class = argparse .ArgumentDefaultsHelpFormatter )
169
- parser .add_argument ("--cpython" , type = str , default = default_cpython_path ,
170
- dest = "cpython" , help = "path to cpython repo" )
171
- parser .add_argument ("--configure" ,
172
- help = "Run configure script prior to generating bindings" ,
173
- action = "store_true" )
174
- parser .add_argument ("--pyruntime" ,
175
- help = "generate offsets for pyruntime" ,
176
- action = "store_true" )
177
- parser .add_argument ("--build" ,
178
- help = "Build python for this version" ,
179
- action = "store_true" )
180
- parser .add_argument ("--all" ,
181
- help = "Build all versions" ,
182
- action = "store_true" )
183
-
184
- parser .add_argument ("versions" , type = str , nargs = '*' , help = 'versions to extract' )
173
+ parser = argparse .ArgumentParser (
174
+ description = "runs bindgen on cpython version" ,
175
+ formatter_class = argparse .ArgumentDefaultsHelpFormatter ,
176
+ )
177
+ parser .add_argument (
178
+ "--cpython" ,
179
+ type = str ,
180
+ default = default_cpython_path ,
181
+ dest = "cpython" ,
182
+ help = "path to cpython repo" ,
183
+ )
184
+ parser .add_argument (
185
+ "--configure" ,
186
+ help = "Run configure script prior to generating bindings" ,
187
+ action = "store_true" ,
188
+ )
189
+ parser .add_argument ("--pyruntime" , help = "generate offsets for pyruntime" , action = "store_true" )
190
+ parser .add_argument ("--build" , help = "Build python for this version" , action = "store_true" )
191
+ parser .add_argument ("--all" , help = "Build all versions" , action = "store_true" )
192
+
193
+ parser .add_argument ("versions" , type = str , nargs = "*" , help = "versions to extract" )
185
194
186
195
args = parser .parse_args ()
187
196
@@ -191,7 +200,16 @@ def extract_bindings(cpython_path, version, configure=False):
191
200
sys .exit (1 )
192
201
193
202
if args .all :
194
- versions = ['v3.8.0b4' , 'v3.7.0' , 'v3.6.6' , 'v3.5.5' , 'v3.4.8' , 'v3.3.7' , 'v3.2.6' , 'v2.7.15' ]
203
+ versions = [
204
+ "v3.8.0b4" ,
205
+ "v3.7.0" ,
206
+ "v3.6.6" ,
207
+ "v3.5.5" ,
208
+ "v3.4.8" ,
209
+ "v3.3.7" ,
210
+ "v3.2.6" ,
211
+ "v2.7.15" ,
212
+ ]
195
213
else :
196
214
versions = args .versions
197
215
if not versions :
0 commit comments