On 25 November 2015 at 07:33, Guido van Rossum firstname.lastname@example.org wrote:
Ooooh, that's probably really old code. I guess for the slots the reasoning is to save on slots. For the public functions, alas it will be hard to know if anyone is depending on it, even if it's undocumented. Perhaps add a deprecation warning to these if the value is NULL for one release cycle?
I did a quick scan for "PyObject_SetAttr", and it turns out PyObject_DelAttr is only a convenience macro for calling PyObject_SetAttr with NULL as the value argument. bltinmodule.c and ceval.c also both include direct calls to PyObject_SetAttr with "(PyObject *)NULL" as the value argument.
Investigating some of the uses that passed a variable as the value argument, one case is the weakref proxy implementation, which uses PyObject_SetAttr on the underlying object in its implementation of the setattr slot in the proxy.
So it looks to me like replicating the NULL-handling behaviour of the slots in the public Set APIs was intentional, and it's just the documentation of that detail that was missed (since most folks presumably use the Del convenience APIs instead).
-- Nick Coghlan | email@example.com | Brisbane, Australia