Skip to content

Commit 295e983

Browse files
committed
More focused version of the changeset
Signed-off-by: Matthew A Johnson <matjoh@microsoft.com>
1 parent 9879c07 commit 295e983

File tree

14 files changed

+88
-231
lines changed

14 files changed

+88
-231
lines changed

Include/internal/pycore_immutability.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ extern "C" {
1212
PyObject* _Py_Freeze(PyObject*);
1313
#define Py_Freeze(op) _Py_Freeze(_PyObject_CAST(op))
1414

15-
PyObject* _Py_FreezeGlobals(void);
16-
17-
bool _Py_GlobalsImmutable_Check(void);
18-
1915
#ifdef __cplusplus
2016
}
2117
#endif

Include/internal/pycore_object.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,7 @@ static inline void _Py_SetImmutable(PyObject *op)
100100
}
101101
#define _Py_SetImmutable(op) _Py_SetImmutable(_PyObject_CAST(op))
102102

103-
/* _Py_ClearImmutable() should only be used during object deallocation and runtime finalization. */
104-
static inline void _Py_ClearImmutable(PyObject *op)
105-
{
106-
if (op) {
107-
op->ob_refcnt &= _Py_REFCNT_MASK;
108-
}
109-
}
110-
#define _Py_ClearImmutable(op) _Py_ClearImmutable(_PyObject_CAST(op))
111-
112-
#define Py_CHECKWRITE(op) ((op) && (!_Py_IsImmutable(op)))
103+
#define Py_CHECKWRITE(op) ((op) && (!_Py_IsImmutable(op) || _Py_IsFinalizing()))
113104
#define Py_REQUIREWRITE(op, msg) {if (Py_CHECKWRITE(op)) { _PyObject_ASSERT_FAILED_MSG(op, msg); }}
114105

115106
static inline void

Lib/test/test_freeze.py

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -400,16 +400,14 @@ def test_weakref(self):
400400
# self.assertTrue(c.val() is obj)
401401
self.assertIsNone(c.val())
402402

403-
# This test will make the Python environment unusable.
404-
# Should perhaps forbid making the frame immutable.
405-
# class TestStackCapture(unittest.TestCase):
406-
# def test_stack_capture(self):
407-
# import sys
408-
# x = {}
409-
# x["frame"] = sys._getframe()
410-
# freeze(x)
411-
# self.assertTrue(isimmutable(x))
412-
# self.assertTrue(isimmutable(x["frame"]))
403+
class TestStackCapture(unittest.TestCase):
404+
def test_stack_capture(self):
405+
import sys
406+
x = {}
407+
x["frame"] = sys._getframe()
408+
freeze(x)
409+
self.assertTrue(isimmutable(x))
410+
self.assertTrue(isimmutable(x["frame"]))
413411

414412
global_test_dict = 0
415413
class TestGlobalDictMutation(unittest.TestCase):
@@ -426,5 +424,39 @@ def test_global_dict_mutation(self):
426424
self.assertRaises(NotWriteableError, f1)
427425

428426

427+
class TestSubclass(unittest.TestCase):
428+
def test_subclass(self):
429+
class C:
430+
def __init__(self, val):
431+
self.val = val
432+
433+
def a(self):
434+
return self.val
435+
436+
def b(self, val):
437+
self.val = val
438+
439+
c_obj = C(1)
440+
freeze(c_obj)
441+
self.assertTrue(isimmutable(c_obj))
442+
self.assertTrue(isimmutable(C))
443+
class D(C):
444+
def __init__(self, val):
445+
super().__init__(val)
446+
self.val2 = val * 2
447+
448+
def b(self):
449+
return self.val2
450+
451+
def c(self, val):
452+
self.val = val
453+
454+
d_obj = D(1)
455+
self.assertEqual(d_obj.a(), 1)
456+
self.assertEqual(d_obj.b(), 2)
457+
self.assertTrue(isinstance(d_obj, C))
458+
self.assertTrue(issubclass(D, C))
459+
460+
429461
if __name__ == '__main__':
430462
unittest.main()

Lib/test/test_freezeglobals.py

Lines changed: 0 additions & 10 deletions
This file was deleted.

Modules/gcmodule.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,6 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate,
10261026
inquiry clear;
10271027
if ((clear = Py_TYPE(op)->tp_clear) != NULL) {
10281028
Py_INCREF(op);
1029-
_Py_ClearImmutable(op);
10301029
(void) clear(op);
10311030
if (_PyErr_Occurred(tstate)) {
10321031
_PyErr_WriteUnraisableMsg("in tp_clear of",

Objects/abstract.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ immutable_error(void)
4040
PyThreadState *tstate = _PyThreadState_GET();
4141
if (!_PyErr_Occurred(tstate)) {
4242
_PyErr_SetString(tstate, PyExc_NotWriteableError,
43-
"can't modify immutable instance");
43+
"cannot modify immutable instance");
4444
}
4545
return NULL;
4646
}

Objects/moduleobject.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,6 @@ _PyModule_Clear(PyObject *m)
602602
{
603603
PyObject *d = ((PyModuleObject *)m)->md_dict;
604604
if (d != NULL){
605-
_Py_ClearImmutable(d);
606605
_PyModule_ClearDict(d);
607606
}
608607
}
@@ -622,8 +621,6 @@ _PyModule_ClearDict(PyObject *d)
622621

623622
int verbose = _Py_GetConfig()->verbose;
624623

625-
// VPYTODO add code to omit immutable keys from this (similar to __builtins__)
626-
627624
/* First, clear only names starting with a single underscore */
628625
pos = 0;
629626
while (PyDict_Next(d, &pos, &key, &value)) {

Objects/object.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2625,7 +2625,6 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg,
26252625
void
26262626
_Py_Dealloc(PyObject *op)
26272627
{
2628-
_Py_ClearImmutable(op);
26292628
PyTypeObject *type = Py_TYPE(op);
26302629
destructor dealloc = type->tp_dealloc;
26312630
#ifdef Py_DEBUG

Objects/typeobject.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5304,7 +5304,6 @@ type_clear(PyTypeObject *type)
53045304
PyType_Modified(type);
53055305
PyObject *dict = lookup_tp_dict(type);
53065306
if (dict) {
5307-
_Py_ClearImmutable(dict);
53085307
PyDict_Clear(dict);
53095308
}
53105309
Py_CLEAR(((PyHeapTypeObject *)type)->ht_module);

Python/bltinmodule.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2772,19 +2772,6 @@ builtin_freeze(PyObject *module, PyObject *obj)
27722772
return Py_Freeze(obj);
27732773
}
27742774

2775-
/*[clinic input]
2776-
freezeglobals as builtin_freezeglobals
2777-
2778-
Make all globals and the global dictionary immutable.
2779-
[clinic start generated code]*/
2780-
2781-
static PyObject *
2782-
builtin_freezeglobals_impl(PyObject *module)
2783-
/*[clinic end generated code: output=4cd596c15daee779 input=b91735d8218dcb6b]*/
2784-
{
2785-
return _Py_FreezeGlobals();
2786-
}
2787-
27882775

27892776
typedef struct {
27902777
PyObject_HEAD
@@ -3086,7 +3073,6 @@ static PyMethodDef builtin_methods[] = {
30863073
BUILTIN_ISSUBCLASS_METHODDEF
30873074
BUILTIN_ISIMMUTABLE_METHODDEF
30883075
BUILTIN_FREEZE_METHODDEF
3089-
BUILTIN_FREEZEGLOBALS_METHODDEF
30903076
BUILTIN_ITER_METHODDEF
30913077
BUILTIN_AITER_METHODDEF
30923078
BUILTIN_LEN_METHODDEF

0 commit comments

Comments
 (0)