Skip to content

Commit e947495

Browse files
committed
in typeNew:
- copy namespace, we are deleting elements from it - do not throw 'conflicts with class variable' for qualname and classcell, they will be removed anyway - remove also qualname, not only classcell from namespace
1 parent 637fbbd commit e947495

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
128128
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.NoGeneralizationNode;
129129
import com.oracle.graal.python.builtins.objects.complex.PComplex;
130+
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins;
130131
import com.oracle.graal.python.builtins.objects.dict.PDict;
131132
import com.oracle.graal.python.builtins.objects.enumerate.PEnumerate;
132133
import com.oracle.graal.python.builtins.objects.floats.FloatBuiltins;
@@ -177,6 +178,7 @@
177178
import com.oracle.graal.python.nodes.ErrorMessages;
178179
import com.oracle.graal.python.nodes.PGuards;
179180
import com.oracle.graal.python.nodes.SpecialAttributeNames;
181+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__QUALNAME__;
180182
import com.oracle.graal.python.nodes.SpecialMethodNames;
181183
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
182184
import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetAnyAttributeNode;
@@ -2074,7 +2076,7 @@ Object type(Object cls, Object obj, PNone bases, PNone dict, PKeyword[] kwds,
20742076
}
20752077

20762078
@Specialization(guards = "isString(wName)")
2077-
Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict namespace, PKeyword[] kwds,
2079+
Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict namespaceOrig, PKeyword[] kwds,
20782080
@CachedLibrary(limit = "4") PythonObjectLibrary lib,
20792081
@CachedLibrary(limit = "2") HashingStorageLibrary nslib,
20802082
@Cached BranchProfile updatedStorage,
@@ -2085,8 +2087,9 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
20852087
@Cached CallNode callSetNameNode,
20862088
@Cached CallNode callInitSubclassNode,
20872089
@Cached CallNode callNewFuncNode,
2090+
@Cached("create(__DICT__)") LookupAttributeInMRONode getDictAttrNode,
20882091
@Cached GetBestBaseClassNode getBestBaseNode,
2089-
@Cached("create(__DICT__)") LookupAttributeInMRONode getDictAttrNode) {
2092+
@Cached DictBuiltins.CopyNode copyDict) {
20902093
// Determine the proper metatype to deal with this
20912094
String name = castStr.execute(wName);
20922095
Object metaclass = calculate_metaclass(frame, cls, bases, lib);
@@ -2096,11 +2099,12 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
20962099
// the new metaclass has the same __new__ function as we are in, continue
20972100
} else {
20982101
// Pass it to the winner
2099-
callNewFuncNode.execute(frame, newFunc, new Object[]{metaclass, name, bases, namespace}, kwds);
2102+
callNewFuncNode.execute(frame, newFunc, new Object[]{metaclass, name, bases, namespaceOrig}, kwds);
21002103
}
21012104
}
21022105

21032106
try {
2107+
PDict namespace = (PDict) copyDict.call(frame, namespaceOrig);
21042108
PythonClass newType = typeMetaclass(frame, name, bases, namespace, metaclass, nslib, getDictAttrNode, getBestBaseNode);
21052109

21062110
for (DictEntry entry : nslib.entries(namespace.getDictStorage())) {
@@ -2132,6 +2136,15 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
21322136
}
21332137
}
21342138

2139+
// delete __qualname__ from namespace
2140+
if (nslib.hasKey(namespace.getDictStorage(), __QUALNAME__)) {
2141+
HashingStorage newStore = nslib.delItem(namespace.getDictStorage(), __QUALNAME__);
2142+
if (newStore != namespace.getDictStorage()) {
2143+
updatedStorage.enter();
2144+
namespace.setDictStorage(newStore);
2145+
}
2146+
}
2147+
21352148
// set __class__ cell contents
21362149
Object classcell = nslib.getItem(namespace.getDictStorage(), __CLASSCELL__);
21372150
if (classcell != null) {
@@ -2434,7 +2447,8 @@ private PTuple copySlots(String className, SequenceStorage slotList, int slotlen
24342447
setSlotItemNode().execute(newSlots, slotName, NoGeneralizationNode.DEFAULT);
24352448
// Passing 'null' frame is fine because the caller already transfers the exception
24362449
// state to the context.
2437-
if (nslib.hasKey(namespace.getDictStorage(), slotName)) {
2450+
if (!slotName.equals(__CLASSCELL__) && !slotName.equals(__QUALNAME__) && nslib.hasKey(namespace.getDictStorage(), slotName)) {
2451+
// __qualname__ and __classcell__ will be deleted later
24382452
throw raise(PythonBuiltinClassType.ValueError, ErrorMessages.S_S_CONFLICTS_WITH_CLASS_VARIABLE, slotName, "__slots__");
24392453
}
24402454
j++;

0 commit comments

Comments
 (0)