mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	compatibility, this required all places where an array of "struct memberlist" structures was declared that is referenced from a type's tp_members slot to change the type of the structure to PyMemberDef; "struct memberlist" is now only used by old code that still calls PyMember_Get/Set. The code in PyObject_GenericGetAttr/SetAttr now calls the new APIs PyMember_GetOne/SetOne, which take a PyMemberDef argument. As examples, I added actual docstrings to the attributes of a few types: file, complex, instance method, super, and xxsubtype.spamlist. Also converted the symtable to new style getattr.
		
			
				
	
	
		
			162 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "Python.h"
 | 
						|
#include "compile.h"
 | 
						|
#include "symtable.h"
 | 
						|
#include "graminit.h"
 | 
						|
#include "structmember.h"
 | 
						|
 | 
						|
PyObject *
 | 
						|
PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno)
 | 
						|
{
 | 
						|
	PySymtableEntryObject *ste = NULL;
 | 
						|
	PyObject *k, *v;
 | 
						|
 | 
						|
	k = PyInt_FromLong(st->st_nscopes++);
 | 
						|
	if (k == NULL)
 | 
						|
		goto fail;
 | 
						|
	v = PyDict_GetItem(st->st_symbols, k);
 | 
						|
	if (v) /* XXX could check that name, type, lineno match */ {
 | 
						|
		Py_INCREF(v);
 | 
						|
		return v;
 | 
						|
	}
 | 
						|
	
 | 
						|
	ste = (PySymtableEntryObject *)PyObject_New(PySymtableEntryObject,
 | 
						|
						    &PySymtableEntry_Type);
 | 
						|
	ste->ste_table = st;
 | 
						|
	ste->ste_id = k;
 | 
						|
 | 
						|
	v = PyString_FromString(name);
 | 
						|
	if (v == NULL)
 | 
						|
		goto fail;
 | 
						|
	ste->ste_name = v;
 | 
						|
	
 | 
						|
	v = PyDict_New();
 | 
						|
	if (v == NULL)
 | 
						|
	    goto fail;
 | 
						|
	ste->ste_symbols = v;
 | 
						|
 | 
						|
	v = PyList_New(0);
 | 
						|
	if (v == NULL)
 | 
						|
	    goto fail;
 | 
						|
	ste->ste_varnames = v;
 | 
						|
 | 
						|
	v = PyList_New(0);
 | 
						|
	if (v == NULL)
 | 
						|
	    goto fail;
 | 
						|
	ste->ste_children = v;
 | 
						|
 | 
						|
	ste->ste_optimized = 0;
 | 
						|
	ste->ste_lineno = lineno;
 | 
						|
	switch (type) {
 | 
						|
	case funcdef:
 | 
						|
	case lambdef:
 | 
						|
		ste->ste_type = TYPE_FUNCTION;
 | 
						|
		break;
 | 
						|
	case classdef:
 | 
						|
		ste->ste_type = TYPE_CLASS;
 | 
						|
		break;
 | 
						|
	case single_input:
 | 
						|
	case eval_input:
 | 
						|
	case file_input:
 | 
						|
		ste->ste_type = TYPE_MODULE;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	if (st->st_cur == NULL)
 | 
						|
		ste->ste_nested = 0;
 | 
						|
	else if (st->st_cur->ste_nested 
 | 
						|
		 || st->st_cur->ste_type == TYPE_FUNCTION)
 | 
						|
		ste->ste_nested = 1;
 | 
						|
	else
 | 
						|
		ste->ste_nested = 0;
 | 
						|
	ste->ste_child_free = 0;
 | 
						|
	ste->ste_generator = 0;
 | 
						|
 | 
						|
	if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
 | 
						|
	    goto fail;
 | 
						|
	
 | 
						|
	return (PyObject *)ste;
 | 
						|
 fail:
 | 
						|
	Py_XDECREF(ste);
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
ste_repr(PySymtableEntryObject *ste)
 | 
						|
{
 | 
						|
	char buf[256];
 | 
						|
 | 
						|
	sprintf(buf, "<symtable entry %.100s(%ld), line %d>",
 | 
						|
		PyString_AS_STRING(ste->ste_name),
 | 
						|
		PyInt_AS_LONG(ste->ste_id),
 | 
						|
		ste->ste_lineno);
 | 
						|
	return PyString_FromString(buf);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
ste_dealloc(PySymtableEntryObject *ste)
 | 
						|
{
 | 
						|
	ste->ste_table = NULL;
 | 
						|
	Py_XDECREF(ste->ste_id);
 | 
						|
	Py_XDECREF(ste->ste_name);
 | 
						|
	Py_XDECREF(ste->ste_symbols);
 | 
						|
	Py_XDECREF(ste->ste_varnames);
 | 
						|
	Py_XDECREF(ste->ste_children);
 | 
						|
	PyObject_Del(ste);
 | 
						|
}
 | 
						|
 | 
						|
#define OFF(x) offsetof(PySymtableEntryObject, x)
 | 
						|
 | 
						|
static PyMemberDef ste_memberlist[] = {
 | 
						|
	{"id",       T_OBJECT, OFF(ste_id), READONLY},
 | 
						|
	{"name",     T_OBJECT, OFF(ste_name), READONLY},
 | 
						|
	{"symbols",  T_OBJECT, OFF(ste_symbols), READONLY},
 | 
						|
	{"varnames", T_OBJECT, OFF(ste_varnames), READONLY},
 | 
						|
	{"children", T_OBJECT, OFF(ste_children), READONLY},
 | 
						|
	{"type",     T_INT,    OFF(ste_type), READONLY},
 | 
						|
	{"lineno",   T_INT,    OFF(ste_lineno), READONLY},
 | 
						|
	{"optimized",T_INT,    OFF(ste_optimized), READONLY},
 | 
						|
	{"nested",   T_INT,    OFF(ste_nested), READONLY},
 | 
						|
	{NULL}
 | 
						|
};
 | 
						|
 | 
						|
PyTypeObject PySymtableEntry_Type = {
 | 
						|
	PyObject_HEAD_INIT(&PyType_Type)
 | 
						|
	0,
 | 
						|
	"symtable entry",
 | 
						|
	sizeof(PySymtableEntryObject),
 | 
						|
	0,
 | 
						|
	(destructor)ste_dealloc,                /* tp_dealloc */
 | 
						|
	0,                                      /* tp_print */
 | 
						|
	0,			               /* tp_getattr */
 | 
						|
	0,					/* tp_setattr */
 | 
						|
	0,			                /* tp_compare */
 | 
						|
	(reprfunc)ste_repr,			/* tp_repr */
 | 
						|
	0,					/* tp_as_number */
 | 
						|
	0,			                /* tp_as_sequence */
 | 
						|
	0,					/* tp_as_mapping */
 | 
						|
	0,					/* tp_hash */
 | 
						|
	0,					/* tp_call */
 | 
						|
	0,					/* tp_str */
 | 
						|
	PyObject_GenericGetAttr,		/* tp_getattro */
 | 
						|
	0,					/* tp_setattro */
 | 
						|
	0,					/* tp_as_buffer */
 | 
						|
	Py_TPFLAGS_DEFAULT,	                /* tp_flags */
 | 
						|
 	0,					/* tp_doc */
 | 
						|
	0,					/* tp_traverse */
 | 
						|
	0,					/* tp_clear */
 | 
						|
	0,					/* tp_richcompare */
 | 
						|
	0,					/* tp_weaklistoffset */
 | 
						|
	0,					/* tp_iter */
 | 
						|
	0,					/* tp_iternext */
 | 
						|
	0,					/* tp_methods */
 | 
						|
	ste_memberlist,				/* tp_members */
 | 
						|
	0,					/* tp_getset */
 | 
						|
	0,					/* tp_base */
 | 
						|
	0,					/* tp_dict */
 | 
						|
	0,					/* tp_descr_get */
 | 
						|
	0,					/* tp_descr_set */
 | 
						|
	0,					/* tp_dictoffset */
 | 
						|
	0,					/* tp_init */
 | 
						|
	0,					/* tp_alloc */
 | 
						|
	0,					/* tp_new */
 | 
						|
};
 |