Skip to content

Commit 9c7dc83

Browse files
committed
Use Py_GIL_DISABLED from sysconfig
1 parent 7073a84 commit 9c7dc83

File tree

5 files changed

+50
-17
lines changed

5 files changed

+50
-17
lines changed

src/build_options.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@ impl BuildOptions {
274274
.get("ABIFLAGS")
275275
.map(ToString::to_string)
276276
.unwrap_or_default();
277+
let gil_disabled = sysconfig_data
278+
.get("Py_GIL_DISABLED")
279+
.map(|x| x == "1")
280+
.unwrap_or_default();
277281
let ext_suffix = sysconfig_data
278282
.get("EXT_SUFFIX")
279283
.context("syconfig didn't define an `EXT_SUFFIX` ಠ_ಠ")?;
@@ -299,6 +303,7 @@ impl BuildOptions {
299303
abiflags,
300304
ext_suffix: ext_suffix.to_string(),
301305
pointer_width: None,
306+
gil_disabled,
302307
},
303308
executable: PathBuf::new(),
304309
platform: None,
@@ -376,6 +381,7 @@ impl BuildOptions {
376381
abiflags: "".to_string(),
377382
ext_suffix: ".pyd".to_string(),
378383
pointer_width: None,
384+
gil_disabled: false,
379385
},
380386
executable: PathBuf::new(),
381387
platform: None,
@@ -402,6 +408,7 @@ impl BuildOptions {
402408
abiflags: "".to_string(),
403409
ext_suffix: ".pyd".to_string(),
404410
pointer_width: None,
411+
gil_disabled: false,
405412
},
406413
executable: PathBuf::new(),
407414
platform: None,
@@ -441,6 +448,7 @@ impl BuildOptions {
441448
abiflags: "".to_string(),
442449
ext_suffix: "".to_string(),
443450
pointer_width: None,
451+
gil_disabled: false,
444452
},
445453
executable: PathBuf::new(),
446454
platform: None,

src/cross_compile.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ KEYS = [
5252
"ABIFLAGS",
5353
"EXT_SUFFIX",
5454
"SOABI",
55+
"Py_GIL_DISABLED",
5556
]
5657
for key in KEYS:
5758
print(key, build_time_vars.get(key, ""))

src/python_interpreter/config.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,20 @@ pub struct InterpreterConfig {
2222
#[serde(rename = "interpreter")]
2323
pub interpreter_kind: InterpreterKind,
2424
/// For linux and mac, this contains the value of the abiflags, e.g. "m"
25-
/// for python3.7m or "dm" for python3.6dm. Since python3.8, the value is
26-
/// empty. On windows, the value was always None.
25+
/// for python3.7m or "dm" for python3.6dm.
26+
///
27+
/// * Since python3.8, the value is empty
28+
/// * Since python3.13, the value is "t" for free-threaded builds.
29+
/// * On Windows, the value was always None.
2730
///
2831
/// See PEP 261 and PEP 393 for details
2932
pub abiflags: String,
3033
/// Suffix to use for extension modules as given by sysconfig.
3134
pub ext_suffix: String,
3235
/// Pointer width
3336
pub pointer_width: Option<usize>,
37+
/// Is GIL disabled, i.e. free-threaded build
38+
pub gil_disabled: bool,
3439
}
3540

3641
impl InterpreterConfig {
@@ -50,6 +55,7 @@ impl InterpreterConfig {
5055
}
5156
let python_ext_arch = target.get_python_ext_arch(python_impl);
5257
let target_env = target.get_python_target_env(python_impl, python_version);
58+
let gil_disabled = abiflags == "t";
5359
match (target.target_os(), python_impl) {
5460
(Os::Linux, CPython) => {
5561
let abiflags = if python_version < (3, 8) {
@@ -67,6 +73,7 @@ impl InterpreterConfig {
6773
abiflags,
6874
ext_suffix,
6975
pointer_width: Some(target.pointer_width()),
76+
gil_disabled,
7077
})
7178
}
7279
(Os::Linux, PyPy) => {
@@ -79,6 +86,7 @@ impl InterpreterConfig {
7986
abiflags: String::new(),
8087
ext_suffix,
8188
pointer_width: Some(target.pointer_width()),
89+
gil_disabled,
8290
})
8391
}
8492
(Os::Macos, CPython) => {
@@ -96,6 +104,7 @@ impl InterpreterConfig {
96104
abiflags,
97105
ext_suffix,
98106
pointer_width: Some(target.pointer_width()),
107+
gil_disabled,
99108
})
100109
}
101110
(Os::Macos, PyPy) => {
@@ -107,6 +116,7 @@ impl InterpreterConfig {
107116
abiflags: String::new(),
108117
ext_suffix,
109118
pointer_width: Some(target.pointer_width()),
119+
gil_disabled,
110120
})
111121
}
112122
(Os::Windows, CPython) => {
@@ -125,9 +135,11 @@ impl InterpreterConfig {
125135
major,
126136
minor,
127137
interpreter_kind: CPython,
138+
// abiflags is always empty on Windows
128139
abiflags: String::new(),
129140
ext_suffix,
130141
pointer_width: Some(target.pointer_width()),
142+
gil_disabled,
131143
})
132144
}
133145
(Os::Windows, PyPy) => {
@@ -140,9 +152,11 @@ impl InterpreterConfig {
140152
major,
141153
minor,
142154
interpreter_kind: PyPy,
155+
// abiflags is always empty on Windows
143156
abiflags: String::new(),
144157
ext_suffix,
145158
pointer_width: Some(target.pointer_width()),
159+
gil_disabled,
146160
})
147161
}
148162
(Os::FreeBsd, CPython) => {
@@ -161,6 +175,7 @@ impl InterpreterConfig {
161175
abiflags,
162176
ext_suffix,
163177
pointer_width: Some(target.pointer_width()),
178+
gil_disabled,
164179
})
165180
}
166181
(Os::NetBsd, CPython) => {
@@ -169,10 +184,10 @@ impl InterpreterConfig {
169184
major,
170185
minor,
171186
interpreter_kind: CPython,
172-
// FIXME: netbsd abiflags for free-threaded python?
173187
abiflags: String::new(),
174188
ext_suffix,
175189
pointer_width: Some(target.pointer_width()),
190+
gil_disabled,
176191
})
177192
}
178193
(Os::OpenBsd, CPython) => {
@@ -185,6 +200,7 @@ impl InterpreterConfig {
185200
abiflags: String::new(),
186201
ext_suffix,
187202
pointer_width: Some(target.pointer_width()),
203+
gil_disabled,
188204
})
189205
}
190206
(Os::Emscripten, CPython) => {
@@ -197,6 +213,7 @@ impl InterpreterConfig {
197213
abiflags: String::new(),
198214
ext_suffix,
199215
pointer_width: Some(target.pointer_width()),
216+
gil_disabled,
200217
})
201218
}
202219
(_, _) => None,
@@ -249,6 +266,7 @@ impl InterpreterConfig {
249266
let mut ext_suffix = None;
250267
let mut abi_tag = None;
251268
let mut pointer_width = None;
269+
let mut build_flags: Option<String> = None;
252270

253271
for (i, line) in lines.enumerate() {
254272
let line = line.context("failed to read line from config")?;
@@ -262,6 +280,7 @@ impl InterpreterConfig {
262280
"ext_suffix" => parse_value!(ext_suffix, value),
263281
"abi_tag" => parse_value!(abi_tag, value),
264282
"pointer_width" => parse_value!(pointer_width, value),
283+
"build_flags" => parse_value!(build_flags, value),
265284
_ => continue,
266285
}
267286
}
@@ -340,19 +359,23 @@ impl InterpreterConfig {
340359
} else {
341360
ext_suffix.context("missing value for ext_suffix")?
342361
};
362+
let gil_disabled = build_flags
363+
.map(|flags| flags.contains("Py_GIL_DISABLED"))
364+
.unwrap_or(false);
343365
Ok(Self {
344366
major,
345367
minor,
346368
interpreter_kind,
347369
abiflags: abiflags.unwrap_or_default(),
348370
ext_suffix,
349371
pointer_width,
372+
gil_disabled,
350373
})
351374
}
352375

353376
/// Generate pyo3 config file content
354377
pub fn pyo3_config_file(&self) -> String {
355-
let build_flags = if self.abiflags == "t" {
378+
let build_flags = if self.gil_disabled {
356379
"Py_GIL_DISABLED"
357380
} else {
358381
""

src/python_interpreter/get_interpreter_metadata.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"system": platform.system().lower(),
3636
# This one is for generating a config file for pyo3
3737
"pointer_width": struct.calcsize("P") * 8,
38+
"gil_disabled": sysconfig.get_config_var("Py_GIL_DISABLED") == 1,
3839
}
3940

4041
print(json.dumps(metadata))

src/python_interpreter/mod.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,13 @@ fn find_all_windows(
245245
Ok(interpreter)
246246
}
247247

248-
fn windows_python_info(executable: &Path) -> Result<Option<InterpreterConfig>> {
248+
struct WindowsPythonInfo {
249+
major: usize,
250+
minor: usize,
251+
pointer_width: Option<usize>,
252+
}
253+
254+
fn windows_python_info(executable: &Path) -> Result<Option<WindowsPythonInfo>> {
249255
let python_info = Command::new(executable)
250256
.arg("-c")
251257
.arg("import sys; print(sys.version)")
@@ -276,12 +282,9 @@ fn windows_python_info(executable: &Path) -> Result<Option<InterpreterConfig>> {
276282
} else {
277283
32
278284
};
279-
Ok(Some(InterpreterConfig {
285+
Ok(Some(WindowsPythonInfo {
280286
major,
281287
minor,
282-
interpreter_kind: InterpreterKind::CPython,
283-
abiflags: String::new(),
284-
ext_suffix: String::new(),
285288
pointer_width: Some(pointer_width),
286289
}))
287290
} else {
@@ -353,6 +356,7 @@ struct InterpreterMetadataMessage {
353356
// comes from `platform.system()`
354357
system: String,
355358
soabi: Option<String>,
359+
gil_disabled: bool,
356360
}
357361

358362
/// The location and version of an interpreter
@@ -425,19 +429,19 @@ fn fun_with_abiflags(
425429
if matches!(message.abiflags.as_deref(), Some("") | None) {
426430
Ok("".to_string())
427431
} else {
428-
bail!("A python 3 interpreter on windows does not define abiflags in its sysconfig ಠ_ಠ")
432+
bail!("A python 3 interpreter on Windows does not define abiflags in its sysconfig ಠ_ಠ")
429433
}
430434
} else if let Some(ref abiflags) = message.abiflags {
431435
if message.minor >= 8 {
432436
// for 3.8, "builds with and without pymalloc are ABI compatible" and the flag dropped
433437
Ok(abiflags.to_string())
434438
} else if (abiflags != "m") && (abiflags != "dm") {
435-
bail!("A python 3 interpreter on linux or mac os must have 'm' or 'dm' as abiflags ಠ_ಠ")
439+
bail!("A python 3 interpreter on Linux or macOS must have 'm' or 'dm' as abiflags ಠ_ಠ")
436440
} else {
437441
Ok(abiflags.to_string())
438442
}
439443
} else {
440-
bail!("A python 3 interpreter on linux or mac os must define abiflags in its sysconfig ಠ_ಠ")
444+
bail!("A python 3 interpreter on Linux or macOS must define abiflags in its sysconfig ಠ_ಠ")
441445
}
442446
}
443447

@@ -695,6 +699,7 @@ impl PythonInterpreter {
695699
.ext_suffix
696700
.context("syconfig didn't define an `EXT_SUFFIX` ಠ_ಠ")?,
697701
pointer_width: None,
702+
gil_disabled: message.gil_disabled,
698703
},
699704
executable,
700705
platform,
@@ -924,11 +929,6 @@ impl PythonInterpreter {
924929
venv_base.as_ref().join("Lib").join("site-packages")
925930
}
926931
}
927-
928-
/// Is this a free threaded python interpreter
929-
pub fn is_free_threaded(&self) -> bool {
930-
self.abiflags == "t"
931-
}
932932
}
933933

934934
impl fmt::Display for PythonInterpreter {

0 commit comments

Comments
 (0)