[Bf-committers] ops functions, parameters, and returns

Richard Olsson r at richardolsson.se
Tue Mar 23 09:02:02 CET 2010

With regards to camelCase, I'm not originally a Python programmer and  
usually do prefer camelCase as well. But Python will be Python, and  
for Python coders the norm seems to be underscores for functions/ 
methods, so I think it should stay that way.


On 23 mar 2010, at 08.36, Campbell Barton wrote:

> Hi Charles,
> Operator access from python is ugly at the moment, its like that room
> you didn't get time to tidy up before the guests (read users) arrive
> ;-)
> Since we didn't keep the door shut you can see the ugly internals.
> At the moment I spend more time on basic problems (except on weekends)
> replies to some of your questions inline.
> On Sun, Mar 21, 2010 at 6:34 PM, Charles Wardlaw
> <cwardlaw at marchentertainment.com> wrote:
>> Hi again Campbell,
>>> Operators are tools and not api functions, the idea is that  
>>> operators
>>> manipulate the context so python can be used to create macro's
>>> What an operator would return isnt always clear, for instance if you
>>> link in objects, would it contain a list of every object, scene and
>>> text blocked linked??
>> Perhaps.  Or if you link in a scene, then the scene would be  
>> returned by itself and would be traversable like bpy.data.scenes.
>> I don't know that linking is a good example-- linking in /  
>> appending objects of different types should, I think, have  
>> different returns.  Linking in a group for character rig linking,  
>> for instance, should return a list like the following:
>> [ 'FINISHED', group, armature1, armature2, ... armatureN, mesh1,  
>> mesh2, ... meshN ]
>> That way scripts could go in and add proxies automatically to all  
>> armature objects that have been linked in.
>> I think that returns should be opened up to discussion, to see how  
>> people would expect things to work.  Linking aside, I would like to  
>> see any add() function return a handle for the added data. So that  
>> something like:
>> ob = bpy.object.addObject(name="Foo")
>> ob.data = bpy.armature.addArmature(name="Bar")
>> would work.  I'd get rid of all the 'FINISHED' returns since it's  
>> just as easy to check for a NoneType return, or an empty tuple.
> This makes sense if we deal with operators as if their main purpose is
> for python API access, A while ago we did talk bout ways operators
> might receive and return 'selection groups', Id still like to allow
> something like this but dont have time at the moment.
>>> however in some cases its really obvious that you would want to  
>>> run an
>>> operator and get a return value, in these cases we should probably
>>> make RNA function calls for these operators (internally they can use
>>> the same C functions).
>>> There are also quite a few cases where the operators should be  
>>> removed
>>> and only have API calls only. Things like "Move Modifier Up" IMHO  
>>> are
>>> not useful as operators.
>>> But then we need to see how rna function calls can be done from  
>>> the UI :S.
>> Heh that's a question beyond me. :)  Although maybe it'd be nice to  
>> provide a function that registers a new operator based on a  
>> function and some arguments -- something similar to how the  
>> partial() stuff works in Python.
>> The main thing is to make the API easy and intuitive for real  
>> coders, but also simple enough to understand for more casual users  
>> so that they can copy and paste from the script log to make their  
>> macros.
>> At the moment I can copy and paste from the script log, but nothing  
>> in the commands there show how to rename objects or how to get at  
>> data.  Something as simple as modifying this call:
>> bpy.ops.mesh.primitive_cube_add(view_align=False,  
>> enter_editmode=False, location=(-0.586031, -0.0568311, 7.21605),  
>> rotation=(0, 0, 0), layer=(False, True, False, False, False, False,  
>> False, False, False, False, False, False, False, False, False,  
>> False, False, False, False, False, False, False, False, False,  
>> True, False, False, False, False, False, False, False))
>> to something more readable, stripping out default value passings:
>> bpy.ops.mesh.primitive_cube_add(name="MyMesh", view_align=False,  
>> enter_editmode=False, location=(-0.586031, -0.0568311, 7.21605))
>> would make life easier on casual scripters.  Now they know exactly  
>> how to change the name just by looking at the code, and they don't  
>> get overwhelmed looking at a really long list of things that are  
>> irrelevant. Incidentally if a location is passed, operators should  
>> bypass the 3D cursor. Or perhaps the functions should have a  
>> standard way of specifying at-cursor placements:
>> bpy.ops.mesh.primitive_cube_add(location=(-0.586031, -0.0568311,  
>> 7.21605)) # ignore the cursor
>> bpy.ops.mesh.primitive_cube_add(placement ='CURSOR') # place at  
>> cursor, ignore location kwarg
>> In this case the default could be placement='WORLD'.  Then when  
>> commands show in the script log, users would see that the location  
>> type is being modified since the UI always places things at the  
>> cursor:
>> bpy.ops.mesh.primitive_cube_add(name="MyMesh", view_align=False,  
>> enter_editmode=False, placement='CURSOR')
>> Sure, you want users to read the manual and learn how to search for  
>> the functions they want, but there are users out there who will  
>> surprise you with what they can do with simple copy and pastes.
> So far operators have been created from a user standpoint, so you get
> odd results when converting an operator into a python function call.
> Agree with some of your suggestions above however not all.
> Operators are a way for python to access user tools, not just a python
> api for all blender functionality.
> So why should you be able to give the name of a new object? (as an
> example), you dont get an option to enter a name as a user so why
> should python?
> Python just has to do what the user would do and rename after
> bpy.ops.mesh.primitive_cube_add(....)
> bpy.context.object.name = "MyMesh"
> Not saying a name argument is bad per se, just that it doesnt always
> make sense to add arguments when the data api can also modify these
> values after.
>>> We could try to make operators behave more like API functions but  
>>> this
>>> is not a small task and not what operators were originally  
>>> designed to
>>> do. so I think its out of the scope of 2.5 tool refactor.
>> And maybe that's not the way to go.  I mean, it's easy enough to  
>> have functions with different kinds of returns, but I understand  
>> that it would go against the original design.
>> At the same time, there could be easier methods for common tasks.   
>> What those functions need to be are anyone's guess at the moment;  
>> I'll keep notes as I go, as should all python coders working with  
>> the Alphas.
>>> Different developers wrote operators, mostly to get blender working
>>> again and not having read how all other operators work. When you try
>>> use operators from python you end up finding many problems like  
>>> this.
>> Ahh okay, no worries.  Moving forwards it would be nice to make  
>> names agree with each other, too.  Things like  
>> bpy.ops.mesh.primitive_circle_add  
>> bpy.ops.armature.bone_primitive_add should match.  (Although I  
>> think that the names should be shortened to addCircle and addBone  
>> respectively.)  On a personal note with regards to naming, it'd be  
>> *awesome* if the underscores were thrown out for camelCase.
> Not going to get into an argument over this one, wasn't my decision
> but Id say we'll stick to underscores.
>>> for data creation and removal though we accept that operators are  
>>> not
>>> ideal and there are existing functions for this
>>> # Example
>>> arm = bpy.data.armatures.new("MyArmature")
>>> obj = bpy.data.objects.new("MyObject", arm)
>>> scene = bpy.context.scene
>>> scene.objects.link(obj)
>> Ahh cool, thanks for that.
>> One last question: is there any particular reason why at this point  
>> objects require edit mode on the script side?  I know there's an  
>> update that's triggered on change from edit to object modes, but to  
>> me it seems like extra steps (not unlike how you have to leave edit  
>> mode to apply a modifier -- if it's smart enough to tell you that,  
>> it should be smart enough to toggle edit mode for you ^_^).
> Id need to see the script, it could be a bug, badly written operator,
> or you might run an operator that requires editmode. AFAIK automatic
> mode switching isn't planed.
>> ~ C
>> PS: Thanks for fixing the help() function.
>> _______________________________________________
>> Bf-committers mailing list
>> Bf-committers at blender.org
>> http://lists.blender.org/mailman/listinfo/bf-committers
> -- 
> - Campbell
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers

More information about the Bf-committers mailing list