summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBrett Simmers <swtaarrs@users.noreply.github.com>2024-03-11 15:02:58 (GMT)
committerGitHub <noreply@github.com>2024-03-11 15:02:58 (GMT)
commit2731913dd5234ff5ab630a3b7f1c98ad79d4d9df (patch)
treec666bae1112581bf0fe4c23ced8d188082cbcefd /Lib
parent546eb7a3be241c5abd8a83cebbbab8c71107edcf (diff)
downloadcpython-2731913dd5234ff5ab630a3b7f1c98ad79d4d9df.zip
cpython-2731913dd5234ff5ab630a3b7f1c98ad79d4d9df.tar.gz
cpython-2731913dd5234ff5ab630a3b7f1c98ad79d4d9df.tar.bz2
gh-116167: Allow disabling the GIL with `PYTHON_GIL=0` or `-X gil=0` (#116338)
In free-threaded builds, running with `PYTHON_GIL=0` will now disable the GIL. Follow-up issues track work to re-enable the GIL when loading an incompatible extension, and to disable the GIL by default. In order to support re-enabling the GIL at runtime, all GIL-related data structures are initialized as usual, and disabling the GIL simply sets a flag that causes `take_gil()` and `drop_gil()` to return early.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/subprocess.py2
-rw-r--r--Lib/test/_test_embed_set_config.py14
-rw-r--r--Lib/test/test_cmd_line.py33
-rw-r--r--Lib/test/test_embed.py2
4 files changed, 50 insertions, 1 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 20db774..1437bf8 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -350,7 +350,7 @@ def _args_from_interpreter_flags():
if dev_mode:
args.extend(('-X', 'dev'))
for opt in ('faulthandler', 'tracemalloc', 'importtime',
- 'frozen_modules', 'showrefcount', 'utf8'):
+ 'frozen_modules', 'showrefcount', 'utf8', 'gil'):
if opt in xoptions:
value = xoptions[opt]
if value is True:
diff --git a/Lib/test/_test_embed_set_config.py b/Lib/test/_test_embed_set_config.py
index 75b6b7d..5ff5218 100644
--- a/Lib/test/_test_embed_set_config.py
+++ b/Lib/test/_test_embed_set_config.py
@@ -9,6 +9,7 @@ import _testinternalcapi
import os
import sys
import unittest
+from test import support
from test.support import MS_WINDOWS
@@ -211,6 +212,19 @@ class SetConfigTests(unittest.TestCase):
self.set_config(use_hash_seed=1, hash_seed=123)
self.assertEqual(sys.flags.hash_randomization, 1)
+ if support.Py_GIL_DISABLED:
+ self.set_config(enable_gil=-1)
+ self.assertEqual(sys.flags.gil, None)
+ self.set_config(enable_gil=0)
+ self.assertEqual(sys.flags.gil, 0)
+ self.set_config(enable_gil=1)
+ self.assertEqual(sys.flags.gil, 1)
+ else:
+ # Builds without Py_GIL_DISABLED don't have
+ # PyConfig.enable_gil. sys.flags.gil is always defined to 1, for
+ # consistency.
+ self.assertEqual(sys.flags.gil, 1)
+
def test_options(self):
self.check(warnoptions=[])
self.check(warnoptions=["default", "ignore"])
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index 6796dc6..c633f64 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -869,6 +869,39 @@ class CmdLineTest(unittest.TestCase):
self.assertEqual(proc.stdout.rstrip(), 'True')
self.assertEqual(proc.returncode, 0, proc)
+ @unittest.skipUnless(support.Py_GIL_DISABLED,
+ "PYTHON_GIL and -X gil only supported in Py_GIL_DISABLED builds")
+ def test_python_gil(self):
+ cases = [
+ # (env, opt, expected, msg)
+ (None, None, 'None', "no options set"),
+ ('0', None, '0', "PYTHON_GIL=0"),
+ ('1', None, '1', "PYTHON_GIL=1"),
+ ('1', '0', '0', "-X gil=0 overrides PYTHON_GIL=1"),
+ (None, '0', '0', "-X gil=0"),
+ (None, '1', '1', "-X gil=1"),
+ ]
+
+ code = "import sys; print(sys.flags.gil)"
+ environ = dict(os.environ)
+
+ for env, opt, expected, msg in cases:
+ with self.subTest(msg, env=env, opt=opt):
+ environ.pop('PYTHON_GIL', None)
+ if env is not None:
+ environ['PYTHON_GIL'] = env
+ extra_args = []
+ if opt is not None:
+ extra_args = ['-X', f'gil={opt}']
+
+ proc = subprocess.run([sys.executable, *extra_args, '-c', code],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ text=True, env=environ)
+ self.assertEqual(proc.returncode, 0, proc)
+ self.assertEqual(proc.stdout.rstrip(), expected)
+ self.assertEqual(proc.stderr, '')
+
@unittest.skipUnless(sys.platform == 'win32',
'bpo-32457 only applies on Windows')
def test_argv0_normalization(self):
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index 55d3acf..ab1d579 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -523,6 +523,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
CONFIG_COMPAT['_pystats'] = 0
if support.Py_DEBUG:
CONFIG_COMPAT['run_presite'] = None
+ if support.Py_GIL_DISABLED:
+ CONFIG_COMPAT['enable_gil'] = -1
if MS_WINDOWS:
CONFIG_COMPAT.update({
'legacy_windows_stdio': 0,