Some things can apparently be done equally well by a constraint or by a driven Object/Pose IPO (e.g. if ObjectA should have the same Z location as ObjectB, either a ‘Copy Location’ constraint or a ‘LocZ’ driven IPO will do the job).
Are there any non-obvious advantages to one or the other?
For example, do they have different behaviour in the presence of cyclic dependencies? Or if we want to get really fancy, how do PyDrivers compare with PyConstraints?
No constraints and driven IPOs are not the same thing .
(e.g. if ObjectA should have the same Z location as ObjectB, either a ‘Copy Location’ constraint or a ‘LocZ’ driven IPO will do the job)
So to do the same thing as a single contraint can do you are going to set up at least 3 driven IPOs for this ?
Aside from the convenience factor (and using the Copy Loc/Rot/Scale is more then a little misleading, since it is the only setup where the driver is the object that mimics its own transformations the only other constraint that you can set up like this is the Transformation constraint), most constraints cannot be set up using IPO drivers . How would you setup a Track To constraint with driven IPOs … Child of … Floor … Follow Path … IK … etc., etc. ?
Are there any non-obvious advantages to one or the other?
Since they are not the same thing using constraints is easier and give you more animation options . The introduction of driven IPOs gives you more flexibility and more layers to work with .
For example, do they have different behaviour in the presence of cyclic dependencies?
I don’t believe so, but illogical hierarchies are possible in almost any set up …
how do PyDrivers compare with PyConstraints?
PyDrivers are single line Python math expressions (so you could for that driven channel make the curve move like a sine curve etc.) but unless you know how to write very complex curve equations it is somewhat limited . PyConstraints on the other hand can handle much more complex non curve math based behaviors . You could for example make a constraint that move X distance and then rotates Y when the parent moves in Z etc. Basically anything the Python API will allow .