[Bf-committers] Blender Python changes

Kai Kostack kaikostack at gmx.net
Wed Oct 26 13:23:27 CEST 2016

Thank you for the explanation. It makes more sense to me now and I see the 
advantages of the changes. However, I still think that the average use case 
would be unlinking without the hassle to handle all references manually for a 
'simple' script. I would consider writing simple scripts even a general user 
requirement and not so much something exclusively reserved for die-hard
add-on development. 
By the way, I realized the ramifications of the changes just in the last two 
days, otherwise I would have voiced up earlier. 
-- Kai

> Gesendet: Mittwoch, 26. Oktober 2016 um 10:29 Uhr 
> Von: "Bastien Montagne" <montagne29 at wanadoo.fr> 
> An: bf-committers at blender.org 
> Betreff: Re: [Bf-committers] Blender Python changes 
> To keeps things short: remove() behavior was previously utterly 
> inconsistent, a few types (Scene, at least, iirc) were also doing an 
> implicit unlink, while most types would not work and error if datablock 
> was still in use. So you had to use an horrible hack (user_clear()) to 
> set ID's usercount to zero before calling remove() (or ensure you 
> removed things in a specific order such that all users got removed 
> before you removed some data), also usercount was not handled correctly 
> in many corner cases, etc. 
> In a word: it could quickly turn into nightmare to clean up some data - 
> and it was *very* easy to make Blender crash in the process. 
> This has been fixed in 2.78, you now can just directly use remove() 
> (with do_unlink option) to get rid of some data-block, without having to 
> care about clearing its usages first, nor its usercount, nor anything 
> else. And remove() behavior has been unified, my decision to keep unlink 
> optional and off by default was for two reasons: 
> - Unlink did not happen at all in most cases (that was the main reason). 
> - And when it comes to handling *a lot* of data-blocks (thousands of 
> them), skipping unlink can be a huge time saver, it avoids several loops 
> over the whole Main database of data-blocks for each removed one. 
> So yes, this is API breakage (in some limited cases, again, iirc only 
> bpy.data.scenes.remove() was implicitly unlinking before) - but there 
> was no other solution, and this area really needed to be cleaned up, one 
> way or the other some default remove() behavior would have changed. By 
> the way, Py API is not really part of the 'we do not break anything in 
> 2.7x series' stance, this goes mostly for the .blend file compatibility. 
> Py API stance has always been 'we *try* not to break anything, unless it 
> is really necessary'. Blender is not a library, but an end-user 
> application, and its API has to reflect changes to its internal 
> behavior, even when things exposed to end user through the UI look the same. 
> Now, maybe I should have rather enabled do_unlink by default, this could 
> have been less disruptive… But would have been much, much nicer to have 
> that kind of topic raised *before* we release. Because now we for sure 
> cannot do anything about it, which is rather frustrating for everybody. 
> Regards, 
> Bastien 
> Le 26/10/2016 à 09:18, Kai Kostack a écrit : 
>> Dear Blender devs, 
>> I'd like to provide some feedback about a recent change in BPY... OK, and 
> share 
>> some frustration about it. ;) 
>> Just until recently you could unlink a lot of datablock types via their 
>> corresponding remove() methods without any problems. Now with Blender 2.78 
>> someone has decided to change some of these methods in a way that they throw 
> an 
>> exception when there are still other users left on a default unlink attempt: 
>> "RuntimeError: Error: Text 'export.txt' must have zero users to be removed, 
>> found 1 (try with do_unlink=True parameter)" 
>> I thought, "Okaaay, just another parameter to add, no problem." - Why that 
>> would be necessary, since you could have checked for other users anyway 
> before 
>> unlinking, was beyond me. - But then I realized that there are 27 datablock 
>> types that use an updated remove() method while others remained unchanged. I 
>> have like 100 scripts for Blender 2.76 at my disposal and ca. 30 of them have 
>> at least one ".remove(" in the code. "Wow, that's a lot of scripts that might 
>> have been broken by now", I thought. Note that you can't easily go over them 
>> and add the parameter because not all remove methods of Blender would accept 
> it 
>> (not to mention general Python list removes). So I had to look up each and 
>> every line with 'remove' in the API if they were changed or not. That was 
> fun. 
>> While the scripts will (probably) all work by now again, I got first 
> complains 
>> that some of my Add-ons wouldn't work with 2.77 builds anymore. Great. To 
> make 
>> a long story short, I have decided to implement BOTH ways of calling remove 
> via 
>> try & except now, just to make sure the code will work in both versions, 2.77 
>> and 2.78. 
>> I remember a statement along the lines that breaking things will be postponed 
>> until 2.8 and that 2.7x should be kept in a working state. - This is not a 
> call 
>> to change it back, I just want to give you a glimpse of what seemingly 
> appears 
>> to be a clever and small change in design can mean to users, and that they 
>> eventually have to include more and more workarounds and hacks just to 
>> circumvent your 'clever design' to make things just work. Sometimes less is 
>> more. 
>> With respect, 
>> -- Kai 
>> _______________________________________________ 
>> Bf-committers mailing list 
>> Bf-committers at blender.org 
>> https://lists.blender.org/mailman/listinfo/bf-committers 
> _______________________________________________ 
> Bf-committers mailing list 
> Bf-committers at blender.org 
> https://lists.blender.org/mailman/listinfo/bf-committers[https://lists.blender.o
> rg/mailman/listinfo/bf-committers]

More information about the Bf-committers mailing list