Skip to content

Commit a5ad1fe

Browse files
committed
[GR-13147] Test and fix writing HiddenKeys to objects with a __dict__
PullRequest: graalpython/334
2 parents 7e383a0 + 3d8f05e commit a5ad1fe

File tree

3 files changed

+33
-10
lines changed

3 files changed

+33
-10
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_assign.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,18 @@ def test_destructuring():
8585
# TODO not supported yet
8686
# a, b, c = "\U0001d49c\U0001d49e\U0001d4b5"
8787
# assert a == '𝒜' and b == '𝒞' and c == '𝒵'
88+
89+
90+
def test_assigning_hidden_keys():
91+
class A():
92+
def __init__(self):
93+
self.__dict__["xyz"] = 1
94+
95+
ary = [A(), A(), A(), A(), A(), A()]
96+
for a in ary:
97+
a.foo = 12
98+
99+
for a in ary:
100+
id(a) # id is stored in a HiddenKey
101+
102+
return

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromObjectNode.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ protected Object readFromDictCached(PythonObject object, Object key,
113113
}
114114

115115
@Specialization(guards = {
116-
"!isDictUnsetOrSameAsStorage(object)",
117-
"!isHiddenKey(key)"
116+
"!isHiddenKey(key)",
117+
"!isDictUnsetOrSameAsStorage(object)"
118118
}, replaces = "readFromDictCached")
119119
protected Object readFromDict(PythonObject object, Object key,
120120
@Cached("create()") HashingStorageNodes.GetItemNode getItemNode) {
@@ -131,7 +131,10 @@ protected Node createReadMessageNode() {
131131
return Message.READ.createNode();
132132
}
133133

134-
@Specialization(guards = "!isPythonObject(object)")
134+
@Specialization(guards = {
135+
"!isHiddenKey(key)",
136+
"!isPythonObject(object)"
137+
})
135138
protected Object readNative(PythonNativeObject object, Object key,
136139
@Cached("create()") GetObjectDictNode getNativeDict,
137140
@Cached("create()") HashingStorageNodes.GetItemNode getItemNode) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ public static WriteAttributeToObjectNode create() {
7777
return WriteAttributeToObjectNodeGen.create();
7878
}
7979

80-
protected boolean isAttrWritable(PythonObject self) {
81-
if (self instanceof PythonClass || self instanceof PFunction || self instanceof PMethod || self instanceof PythonModule || self instanceof PBaseException) {
80+
protected boolean isAttrWritable(PythonObject self, Object key) {
81+
if (isHiddenKey(key) || self instanceof PythonClass || self instanceof PFunction || self instanceof PMethod || self instanceof PythonModule || self instanceof PBaseException) {
8282
return true;
8383
}
8484
return !exactBuiltinInstanceProfile.profileIsAnyBuiltinObject(self);
@@ -95,7 +95,7 @@ private void handlePythonClass(PythonObject object, Object key) {
9595
// write to the DynamicObject
9696
@Specialization(guards = {
9797
"object == cachedObject",
98-
"isAttrWritable(object) || isHiddenKey(key)"
98+
"isAttrWritable(object, key)"
9999
}, assumptions = {
100100
"singleContextAssumption",
101101
"dictUnsetOrSameAsStorageAssumption"
@@ -110,8 +110,8 @@ protected boolean writeToDynamicStorageCached(PythonObject object, Object key, O
110110
}
111111

112112
@Specialization(guards = {
113-
"isAttrWritable(object) || isHiddenKey(key)",
114-
"isDictUnsetOrSameAsStorage(object)"
113+
"isAttrWritable(object, key)",
114+
"isHiddenKey(key) || isDictUnsetOrSameAsStorage(object)"
115115
}, replaces = "writeToDynamicStorageCached")
116116
protected boolean writeToDynamicStorage(PythonObject object, Object key, Object value,
117117
@Cached("create()") WriteAttributeToDynamicObjectNode writeAttributeToDynamicObjectNode) {
@@ -122,7 +122,8 @@ protected boolean writeToDynamicStorage(PythonObject object, Object key, Object
122122
// write to the dict
123123
@Specialization(guards = {
124124
"object == cachedObject",
125-
"!dictUnsetOrSameAsStorageAssumption.isValid()"
125+
"!isHiddenKey(key)",
126+
"!dictUnsetOrSameAsStorageAssumption.isValid()",
126127
}, assumptions = {
127128
"singleContextAssumption"
128129
})
@@ -144,6 +145,7 @@ protected boolean writeToDictCached(PythonObject object, Object key, Object valu
144145
}
145146

146147
@Specialization(guards = {
148+
"!isHiddenKey(key)",
147149
"!isDictUnsetOrSameAsStorage(object)"
148150
}, replaces = "writeToDictCached")
149151
protected boolean writeToDict(PythonObject object, Object key, Object value,
@@ -160,7 +162,10 @@ protected boolean writeToDict(PythonObject object, Object key, Object value,
160162
return true;
161163
}
162164

163-
@Specialization(guards = "!isPythonObject(object)")
165+
@Specialization(guards = {
166+
"!isHiddenKey(key)",
167+
"!isPythonObject(object)"
168+
})
164169
protected boolean readNative(PythonNativeObject object, Object key, Object value,
165170
@Cached("create()") GetObjectDictNode getNativeDict,
166171
@Cached("create()") HashingCollectionNodes.SetItemNode setItemNode) {

0 commit comments

Comments
 (0)