Python module calls PyObject_GenericGetAttr/PyObject_GenericSetAttr pair to do attribute lookup. (moduleobject.c,object.c) IMO it adds unnecessary overhead, and could be replaced with a bit simplified functions. [1] To get an object's dictionary _PyObject_GetDictPtr function is used (inlined in PyObject_GenericGetAttr). But in module case we can get the dictionary without any call: PyObject *dict = ((PyModuleObject *)obj)->md_dict; [2] If module(tp)->tp_dict == NULL PyType_Ready is called in PyObject_GenericGetAttr. Well , I am not sure if all this stuff added to module type with PyType_Ready is really necessary but instead of calling _PyType_Lookup machinery a simple: if (strcmp(PyString_AS_STRING(name/*attr*/),"__dict__")==0) (+ PyErr_SetString(PyExc_TypeError, "readonly attribute") for setattr function) could be used to access readonly module "__dict__" attribute. The solution I am proposing is probably less elegant than PyObject_GenericGetAttr/PyObject_GenericSetAttr but if it could speed up Python a bit ? If someone would like to test such modified modules, binaries for Windows of my small C extension - modeler.pyd are available at: http://www.wiktorsadowski.com/Python Importing modeler will replace module tp_getattro/ tp_setattro with new functions, and will enable faster access to modules' attributes. (if no other modeler features are used) Regards Wiktor Sadowski ___________________________________________________________________ A new getattr for module tp_getattro could look like this: (the settattr could be simplified as well) PyObject * PyObject_ModuleGetAttr(PyObject *obj, PyObject *name) { PyObject *res = NULL; PyTypeObject *tp = obj->ob_type; PyObject *dict = ((PyModuleObject *)obj)->md_dict; /*string check stuff - no changes*/ if (dict == NULL) { /* it shouldn't happen! */ ((PyModuleObject *)obj)->md_dict=Py_DictNew();/*?*/ } if (strcmp(PyString_AS_STRING(name),"__dict__")==0){ Py_INCREF(dict); return dict; } res = PyDict_GetItem(dict, name); if (res != NULL) { Py_INCREF(res); Py_XDECREF(name); return res; } PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", tp->tp_name, PyString_AS_STRING(name)); }
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4