Open github-actions[bot] opened 2 months ago
As this is a common pattern
internal static IntPtr GetAttr(PyObject ob, string name)
{
/* TODO: Consider interning/caching the name value */
nint pyName = AsPyUnicodeObject(name);
nint pyAttr = Raw.PyObject_GetAttr(ob.ptr, pyName);
Raw.Py_DecRef(pyName);
return pyAttr;
}
what about:
internal static IntPtr GetAttr(PyObject ob, string name)
{
fixed (char* c = s)
{
nint pyName = AsPyUnicodeObjectPointingToCharacters(c);
nint pyAttr = Raw.PyObject_GetAttr(ob.ptr, pyName.ptr);
Raw.Py_DecRef(pyName);
}
return pyAttr;
}
additional APIs in this format might be usefull for somebody:
internal static IntPtr GetAttr(PyObject ob, byte *name, int encoding)
{
nint pyName = AsPyUnicodeObjectPointingToBytesEncodedAs(name, encoding);
nint pyAttr = Raw.PyObject_GetAttr(ob.ptr, pyName.ptr);
Raw.Py_DecRef(pyName);
return pyAttr;
}
Don't know how much a stack based aproach would benefit - but it is possible by checking if the called code doesn't pass the ptr to others which might use it later...
If we do a real caching by holding the reference beyond a single call - does this work with multiple interpreters?
My proposed solution does work for those who know that their call in PyObject_GetAttr won't "copy" the pyName
Due to the nature of Python this can not be assumed for all cases. But: if a CSnakes user (the C# / Python developer) knows what he is doing - e.g. he knows such optimization would work - he should be able to use it.
https://github.com/tonybaloney/CSnakes/blob/b3afc46ce3168f00ac86b461dd3a2fb0cd4320ea/src/CSnakes.Runtime/CPython/Object.cs#L1