Skip to content

Commit b65259d

Browse files
authored
Support frozen sys module in _bootstrap (#96)
* Support frozen sys module in _bootstrap * Make CI slightly greener
1 parent dae95ca commit b65259d

5 files changed

Lines changed: 50 additions & 8 deletions

File tree

Include/internal/pycore_immutability.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@ extern "C" {
88
# error "Py_BUILD_CORE must be defined to include this header"
99
#endif
1010

11-
typedef struct _Py_hashtable_t _Py_hashtable_t;
12-
1311
struct _Py_immutability_state {
1412
int late_init_done;
15-
_Py_hashtable_t *shallow_immutable_types;
16-
_Py_hashtable_t *warned_types;
13+
struct _Py_hashtable_t *shallow_immutable_types;
14+
struct _Py_hashtable_t *warned_types;
1715
// With the pre-freeze hook it can happen that freeze calls are
1816
// nested. This is stack of the enclosing freeze states.
1917
struct FreezeState *freeze_stack;

Lib/importlib/_bootstrap.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,30 @@ def _wrap(new, old):
4444
setattr(new, replace, getattr(old, replace))
4545
new.__dict__.update(old.__dict__)
4646

47+
def _module_type():
48+
sys_type = type(sys)
49+
if sys_type.__name__ == "module":
50+
return sys_type
51+
52+
# The `sys` module is immutable, we need to get the module type
53+
# another way...
54+
mods = [_bootstrap_external, _thread, _warnings, _weakref]
55+
for m in mods:
56+
if type(m).__name__ == "module":
57+
return type(m)
58+
59+
for m in sys.mut_modules.values():
60+
if type(m).__name__ == "module":
61+
return type(m)
62+
63+
# There are other ways to make this work, we can for example
64+
# pass in the module type into a global variable in this script
65+
# or store the module in a global. This is a bridge we can cross,
66+
# when we get there.
67+
raise Exception("sys and all other modules currently accessible are immutable, this is bad")
4768

4869
def _new_module(name):
49-
return type(sys)(name)
70+
return _module_type()(name)
5071

5172

5273
# Module-level locking ########################################################
@@ -1527,7 +1548,7 @@ def _setup(sys_module, _imp_module):
15271548
sys = sys_module
15281549

15291550
# Set up the spec for existing builtin/frozen modules.
1530-
module_type = type(sys)
1551+
module_type = _module_type()
15311552
for name, module in sys.modules.items():
15321553
if isinstance(module, module_type):
15331554
if name in sys.builtin_module_names:

Objects/moduleobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,7 @@ PyTypeObject _PyImmModule_Type = {
16571657
0, /* tp_dictoffset */
16581658
module___init__, /* tp_init */
16591659
0, /* tp_alloc */
1660-
.tp_new = NULL, /* Intentionally NULL since it should not be instanciated. */
1660+
.tp_new = NULL, /* Intentionally NULL since it should not be instantiated. */
16611661
.tp_free = PyObject_GC_Del, /* tp_free */
16621662
.tp_reachable = module_reachable,
16631663
};

Python/pystate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,7 @@ PyModuleObject* _PyInterpreterState_GetModuleState(PyObject *mod) {
13861386
if (modules_mod == mod) {
13871387
// The modules in `sys.modules` is this frozen mod but there is
13881388
// no mutable state in `sys.mut_modules`, probably because it was
1389-
// unimported? Either way:
1389+
// unimported? Either way:
13901390
// Remove `mod` from `sys.modules` and trigger a reimport.
13911391
if (PyDict_DelItem(modules, self->md_name) < 0) {
13921392
Py_DECREF(modules_mod);

Tools/c-analyzer/cpython/globals-to-fix.tsv

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,29 @@ filename funcname name reason
33

44
# These are all variables that we will be making non-global.
55

6+
###############################
7+
## Pyrona
8+
9+
## ---------------
10+
## Safe
11+
12+
Python/immutability.c - PostOrderMarker -
13+
Python/immutability.c - EnsureVisitedMarker -
14+
Objects/weakrefobject.c - _PyWeakref_Lock -
15+
16+
## ---------------
17+
## Lazy
18+
19+
20+
## ---------------
21+
## Tests
22+
23+
Modules/_test_reachable.c - HasTraverseNoReachable_Type -
24+
Modules/_test_reachable.c - NoTraverseNoReachable_Type -
25+
Modules/_test_reachable.c - HasReachable_Type -
26+
Modules/_test_reachable.c - ShallowImmutable_Type -
27+
28+
629
##################################
730
## global objects to fix in core code
831

0 commit comments

Comments
 (0)