[Python-Dev] other "magic strings" issues
Alex Martelli
aleaxit at yahoo.com
Sun Nov 9 05:43:32 EST 2003
On Sunday 09 November 2003 01:28, Martin v. Löwis wrote:
> Alex Martelli wrote:
> > [[ I meant -- but didn't say out loud!-) -- "without changing the
> > current bytecode-level logic". The change I proposed and experimented
> > with for strings' is... methods is localized to stringobject.c and
> > requires changing nothing except the details of string objects'
> > implementation ]]
>
> Then I probably don't understand what you are suggesting. What would
> LOAD_ATTR do if the object is a string, the attribute is "isdigit", and
> you were allowed to assume that the result won't depend on factors that
> may change over time?
The LOAD_ATTR attribute, using exactly the machinery it uses today,
gets to PyString_Type's tp_getattro slot, which is unchanged:
PyObject_GenericGetAttr, /* tp_getattro */
Only one slot in PyString_Type is changed at all:
string_getsets, /* tp_getset */
and it's changed from being 0 as it is now to pointing to:
static PyGetSetDef string_getsets[] = {
{"isdigit", (getter)string_isdigit_getter, 0, isdigit_getter__doc__},
/* other getsets snipped */
{0}
};
string_isdigit_getter is quite similar to today's string_isdigit *EXCEPT*
that instead of returning True or False (via PyBool_FromLong(1) etc)
it returns one of two nullary callables which will always return True or
respectively False when called:
static PyObject * _isdigit_return_true = 0;
static PyObject * _isdigit_return_false = 0;
static PyObject * _isdigit_true_returner(PyObject* ignore_self)
{
Py_RETURN_TRUE;
}
static PyObject * _isdigit_false_returner(PyObject* ignore_self)
{
Py_RETURN_FALSE;
}
static PyMethodDef _str_bool_returners[] = {
{"isdigit", (PyCFunction)_isdigit_false_returner, METH_NOARGS},
{"isdigit", (PyCFunction)_isdigit_true_returner, METH_NOARGS},
/* other "bool returners" snipped */
{0}
};
static PyObject*
_return_returner(PyObject** returner, PyMethodDef *returner_method_def)
{
if(!*returner)
*returner = PyCFunction_New(returner_method_def, 0);
Py_INCREF(*returner);
return *returner;
}
so string_isdigit_getter uses
return _return_returner(&_isdigit_return_true, _str_bool_returners+1);
where string_isdigit would instead use
return PyBool_FromLong(1);
That's all there is to my proposal (we'd have another pair of 'bool
returners' for isspace -- I think there are no other is... methods of
strings suitable for this, given locale dependency of letter/upper/lower
concepts) -- just a simple way to exploit descriptors to avoid creating
bound-method objects -- with a speedup of 30% compared with the
current implementations of isdigit and isspace (but the `in` operator is
jet another 30% faster in both cases).
Your proposal is vastly more ambitious and interesting, it seems to me.
Alex
More information about the Python-Dev
mailing list