API Cleanup::Remove Inconsistencies
As the next phase of the BPy API Cleanup, we would like to flush out inconsistences in the API.
Our eventual goal is to make the API consistant and move to accessing attributes directly, rather than using the x.getSomething() / x.setSomething() interface.
Examples of what we are looking for are
- places where get and set methods do not take or return the same types
- methods where we can replace string arguments with dictionary constants
- lists vs. multiple args
- use of sequence protocol instead of method with index to access data in types with sequences. example: points[i] = x rather than points.set(index, val)
- implement iterators for types with sequences of data
- prefer exceptions over returning error codes. example: Object.Get('some_name') should throw an exception when 'some_name' does not exist rather than returning None. This will be unfamiliar to novice scripters but it provides better error handling, especially when trying to integrate scripts together.
Add and discuss your issues below-- StephenSwaney - 20 Jul 2005
-- KenHughes - 12 Aug 2005
- inconsistency of "R/G/B/A" and "r/g/b/a" attribute names in various modules
- "bitmask" flags should be accessed consistently. Some getter/ setters just pass ints for whole flags, others toggle individual bits. Some require user to know which bits do what, others hide it (ex: see NMFace.flag and NMFace.hide).
- "Layer": are there 24 or 20 (what's the correct mask)? Ex: Object.Layer uses 0xffffff, Scene.Layer uses 0x0fffff (Object.c actually checks for 24 bits but on error raises an exception which says "bitmask must have from 1 up to 20 bits set")
- Lattice.getMode() returns string, Lattice.setMode() takes integer
- BPy Object uses two different matrix types (see Object.getMatrix() and Object.getInverseMatrix()
- Particle.setChild() takes four floats as parameters, but casts to shorts (documentation also says method takes floats)
- Particle.getMat()/setMat() also use floats when data are shorts (documentation also says methods use floats)
- neither Texture.setNoiseBasis() and Texture.setDistNoise() allow noise settings for wood or marble types
- getters and setters that don't take the same types:
- vector = NMesh.NMVert.uvco / NMesh.NMVert.uvco = (float,float<,float>)
- int = Camera.getMode() / Camera.setMode(str=None,str=None)
- int = Camera.getType() / Camera.setType(str)
- int = Lamp.getMode() / Lamp.setMode(str=None,str=None,...,str=None)
- (str,str,str) = Lattice.getKeyTypes() / Lattice.setKeyTypes(int,int,int)
- str = Lattice.getMode() / Lattice.setMode(int)
- int = Scene.Radio.getMode() / Scene.Radio.setMode(str=None,str=None)
- tuple = Text3d.getDrawMode() / Text3d.setDrawMode(tuple or constant) : getDrawMode() can return tuple with 0 items, setDrawMode only accepts tuple with 1 to 3 items (and 0 or 1 item tuples are rare; should these use lists instead?)
Methods and attributes using string arguments (replace with dictionary constants)
-- KenHughes - 15 Aug 2005
Note: even for some methods which use int arguments, wouldn't it make sense for them to also use const dicts (like Blender.Lamp.Modes has)? I've included them below, noting them with [int] versus [str].
- Effect.flag [int]
- Effect.type [int]
- Object.drawMode [int]
- Object.drawType [int]
- Texture.noiseType [str]
- Camera.New(type='persp',...) [str]
- Camera.setMode(mode1=None,mode2=None) [str]
- Effect.New(type) [str]
- Effect.getFlag() / Effect.setFlag(type) [int]
- Effect.getType() / Effect.setType(type) [int]
- Ipo.New(type,...) [str]
- Lamp.New(type='Lamp',...) [str]
- Lamp.setMode(m=None,m2=None,m3=None,m4=None,m5=None,m6=None,m7=None,m8=None) [str]
- Lamp.setType(type) [str]
- Object.New(type,...) [[str]
- Object.getDrawMode() / Object.setDrawMode(drawmode) [int]
- Object.getDrawType() / Object.setDrawType(drawtype) [int]
- Texture.setDistMetric(type) [str]
- Texture.setDistNoise(type) [str]
- Texture.getExtend() / Texture.setExtend(extendmode) [str]
- Texture.setFlags(f=None,f2=None,f3=None) [str]
- Texture.setImageFlags(f=None,f2=None,f3=None,and_so_on=None) [str]
- Texture.setNoiseBasis(type) [str]
- Texture.setSType(stype) [str]
- Texture.getType() / Texture.setType(type) [str]
- World.getMistype() / World.setMistype (type) [int]
- World.getMode() / World.setMode (type) [int]
- World.getSkytype() / World.setSkytype (type) [int] all .getScriptLinks(...,event) [str] all .addScriptLink(event) [str]
Documentation inconsistencies and errors
- http://www.blender3d.org/documentation/237PythonDoc/API_related-module.html - space handler example:
The example for using script handlers does not work. The first error is attempting to import 'DRAW' from Blender, the module name is 'Draw'. Next a return statement is used outside of a function, this raises a SyntaxError. Lastly the final line should go under the first two conditionals, otherwise the program will swallow all input.
New Example: # SPACEHANDLER.VIEW3D.EVENT import Blender from Blender import Draw evt = Blender.event if evt == Draw.LEFTMOUSE: print "Swallowing the left mouse button event" Blender.event = None elif evt == Draw.AKEY: print "Swallowing the 'a' key event" Blender.event = None else: print "Let the 3D View itself process this event:", evt pass
It would also be nice if the example showed how to use an event handler together with a draw handler. I would write an example, but I don't know how it is expected to be done.
-- KenHughes - 12 Aug 2005
- doc/Font.py: documentation just plain wrong: describes methods which don't exist, doesn't describe ones that do exist.
- doc/Material.py: documentataion says setMode() takes up to 22 strings; there are 27 different possible bit (some are duplicates because of Halo). Needs to be more clear on what combination of bits go together. And are there really 22 possible bits which can be set simultaneously? I can only find 19 bits used in the bitmask.
- doc/Metaball.py: need documentation on BPy Metaelem objects.
- doc/Object.py: documentation for Soft Body, Particle Interaction listed in "Properties"
- doc/Render.py: need documentation for currentFrame() method.
- doc/Texture.py: doesn't mention all STypes ("DistortedNoise"), doesn't mention newer methods like setNoiseMethod(), setDistNoise(), setDistMetric()
- doc/World.py: documentation for setStar()/getStar() methods says they use list of 9 floats when they in fact only use 7
- BPy Text3d is missing wrappers for intrr's new text stuff (word spacing, flush just, etc); of course, documentation is also missing
- Should module constants be "clamped" to be sure the right constant is used in each setter?
- Should all flags/modes use module constants?
- Should all module constants and const dictionary keys be upper-case (see Blender.Scene.Radio.Modes)?
- Should module constants always be included in dictionaries separate from the module's dictionary, especially when they are part of some logical colletion? Example: Blender.Object.PI_STRENGTH
- Should constants for IPO baking be added to a separate dictionary, like other "constant classes" (for example, Blender.Material.Shaders)?
I think that flags should be presented to scripts as Python Booleans. (that's what I did in my patch: http://projects.blender.org/tracker/?func=detail&aid=2869&group_id=9&atid=127) -- YehoshuaSapir - 15 Aug 2005