mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	Disallow class assignment completely unless both old and new are heap
types. This prevents nonsense like 2.__class__ = bool or True.__class__ = int.
This commit is contained in:
		
							parent
							
								
									e05f65a0c6
								
							
						
					
					
						commit
						40af889081
					
				
					 2 changed files with 14 additions and 6 deletions
				
			
		| 
						 | 
					@ -2478,6 +2478,11 @@ def setclass():
 | 
				
			||||||
    cant(C(), object)
 | 
					    cant(C(), object)
 | 
				
			||||||
    cant(object(), list)
 | 
					    cant(object(), list)
 | 
				
			||||||
    cant(list(), object)
 | 
					    cant(list(), object)
 | 
				
			||||||
 | 
					    class Int(int): __slots__ = []
 | 
				
			||||||
 | 
					    cant(2, Int)
 | 
				
			||||||
 | 
					    cant(Int(), int)
 | 
				
			||||||
 | 
					    cant(True, int)
 | 
				
			||||||
 | 
					    cant(2, bool)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setdict():
 | 
					def setdict():
 | 
				
			||||||
    if verbose: print "Testing __dict__ assignment..."
 | 
					    if verbose: print "Testing __dict__ assignment..."
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1745,6 +1745,13 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	new = (PyTypeObject *)value;
 | 
						new = (PyTypeObject *)value;
 | 
				
			||||||
 | 
						if (!(new->tp_flags & Py_TPFLAGS_HEAPTYPE) ||
 | 
				
			||||||
 | 
						    !(old->tp_flags & Py_TPFLAGS_HEAPTYPE))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
 | 
								     "__class__ assignment: only for heap types");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (new->tp_dealloc != old->tp_dealloc ||
 | 
						if (new->tp_dealloc != old->tp_dealloc ||
 | 
				
			||||||
	    new->tp_free != old->tp_free)
 | 
						    new->tp_free != old->tp_free)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -1771,13 +1778,9 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
 | 
				
			||||||
			     old->tp_name);
 | 
								     old->tp_name);
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (new->tp_flags & Py_TPFLAGS_HEAPTYPE) {
 | 
					 | 
				
			||||||
	Py_INCREF(new);
 | 
						Py_INCREF(new);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	self->ob_type = new;
 | 
						self->ob_type = new;
 | 
				
			||||||
	if (old->tp_flags & Py_TPFLAGS_HEAPTYPE) {
 | 
					 | 
				
			||||||
	Py_DECREF(old);
 | 
						Py_DECREF(old);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue