mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Make str and tuple types subclassable.
This commit is contained in:
		
							parent
							
								
									147b13c069
								
							
						
					
					
						commit
						ae960afb5e
					
				
					 2 changed files with 54 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -2683,13 +2683,17 @@ string_methods[] = {
 | 
			
		|||
	{NULL,     NULL}		     /* sentinel */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
staticforward PyObject *
 | 
			
		||||
str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
 | 
			
		||||
 | 
			
		||||
static PyObject *
 | 
			
		||||
string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *x = NULL;
 | 
			
		||||
	static char *kwlist[] = {"object", 0};
 | 
			
		||||
 | 
			
		||||
	assert(type == &PyString_Type);
 | 
			
		||||
	if (type != &PyString_Type)
 | 
			
		||||
		return str_subtype_new(type, args, kwds);
 | 
			
		||||
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:str", kwlist, &x))
 | 
			
		||||
		return NULL;
 | 
			
		||||
	if (x == NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -2697,6 +2701,24 @@ string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
			
		|||
	return PyObject_Str(x);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *
 | 
			
		||||
str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *tmp, *new;
 | 
			
		||||
	int n;
 | 
			
		||||
 | 
			
		||||
	assert(PyType_IsSubtype(type, &PyString_Type));
 | 
			
		||||
	tmp = string_new(&PyString_Type, args, kwds);
 | 
			
		||||
	if (tmp == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	assert(PyString_Check(tmp));
 | 
			
		||||
	new = type->tp_alloc(type, n = PyString_GET_SIZE(tmp));
 | 
			
		||||
	if (new == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	memcpy(PyString_AS_STRING(new), PyString_AS_STRING(tmp), n+1);
 | 
			
		||||
	return new;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char string_doc[] =
 | 
			
		||||
"str(object) -> string\n\
 | 
			
		||||
\n\
 | 
			
		||||
| 
						 | 
				
			
			@ -2724,7 +2746,7 @@ PyTypeObject PyString_Type = {
 | 
			
		|||
	PyObject_GenericGetAttr,		/* tp_getattro */
 | 
			
		||||
	0,					/* tp_setattro */
 | 
			
		||||
	&string_as_buffer,			/* tp_as_buffer */
 | 
			
		||||
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 | 
			
		||||
	string_doc,				/* tp_doc */
 | 
			
		||||
	0,					/* tp_traverse */
 | 
			
		||||
	0,					/* tp_clear */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -475,13 +475,17 @@ tuplerichcompare(PyObject *v, PyObject *w, int op)
 | 
			
		|||
	return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
staticforward PyObject *
 | 
			
		||||
tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
 | 
			
		||||
 | 
			
		||||
static PyObject *
 | 
			
		||||
tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *arg = NULL;
 | 
			
		||||
	static char *kwlist[] = {"sequence", 0};
 | 
			
		||||
 | 
			
		||||
	assert(type == &PyTuple_Type);
 | 
			
		||||
	if (type != &PyTuple_Type)
 | 
			
		||||
		return tuple_subtype_new(type, args, kwds);
 | 
			
		||||
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -491,6 +495,29 @@ tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
			
		|||
		return PySequence_Tuple(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static PyObject *
 | 
			
		||||
tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *tmp, *new, *item;
 | 
			
		||||
	int i, n;
 | 
			
		||||
 | 
			
		||||
	assert(PyType_IsSubtype(type, &PyTuple_Type));
 | 
			
		||||
	tmp = tuple_new(&PyTuple_Type, args, kwds);
 | 
			
		||||
	if (tmp == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	assert(PyTuple_Check(tmp));
 | 
			
		||||
	new = type->tp_alloc(type, n = PyTuple_GET_SIZE(tmp));
 | 
			
		||||
	if (new == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	for (i = 0; i < n; i++) {
 | 
			
		||||
		item = PyTuple_GET_ITEM(tmp, i);
 | 
			
		||||
		Py_INCREF(item);
 | 
			
		||||
		PyTuple_SET_ITEM(new, i, item);
 | 
			
		||||
	}
 | 
			
		||||
	Py_DECREF(tmp);
 | 
			
		||||
	return new;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char tuple_doc[] =
 | 
			
		||||
"tuple(sequence) -> list\n\
 | 
			
		||||
\n\
 | 
			
		||||
| 
						 | 
				
			
			@ -529,7 +556,8 @@ PyTypeObject PyTuple_Type = {
 | 
			
		|||
	PyObject_GenericGetAttr,		/* tp_getattro */
 | 
			
		||||
	0,					/* tp_setattro */
 | 
			
		||||
	0,					/* tp_as_buffer */
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
 | 
			
		||||
		Py_TPFLAGS_BASETYPE,		/* tp_flags */
 | 
			
		||||
	tuple_doc,				/* tp_doc */
 | 
			
		||||
 	(traverseproc)tupletraverse,		/* tp_traverse */
 | 
			
		||||
	0,					/* tp_clear */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue