How to avoid permutations of vector objects when dumping data? I'm trying to write a script which recursively dumps all data found in bpy.data.
The idea is when a .blend file is messed up I could compare it with an earlier version and could find the exact changes.

Running the script below the default scene already creates a 160 MB file this is caused by lines like:

bpy.data.brushes.clone_offset.xx.xx.x=0.0
bpy.data.brushes.clone_offset.xx.xxx.x=0.0
bpy.data.brushes.clone_offset.xx.xxxx.x=0.0
bpy.data.brushes.clone_offset.xx.xxxy.x=0.0


I don't understand where they do come from, how should I cope with vector objects?

The full script:

blender.exe --background -P dump.py


.

import bpy

map={}

def dump(obj, name="", level=0):
    if level &gt; 5:
        return
    print("call %d obj=%s type=%s" % (level, str(obj), str(type(obj))))
    if str(type(obj)) in ("&lt;class 'builtin_function_or_method'&gt;",):#"&lt;class 'Vector'&gt;"):
        return
    if id(obj) in map:
        print("already dumped=%s" % obj )
        return
    map[id(obj)]=obj

    if str(type(obj)) == "&lt;class 'bpy_prop_collection'&gt;":
        print("isbpy_prop")
        for item in obj:
            dump( item, name , level+1)
            return

    if str(type(obj)) == "&lt;class 'tuple'&gt;":
        idx=0
        for item in obj:
            dump( item, name + "[" +str(idx) + "]", level+1)
            idx = idx+1
            return;
    for attr in dir(obj):
       if not hasattr(obj, attr ) or attr.startswith("__") or attr in ("bl_rna","base","rna_type"):
           continue
       val = getattr(obj, attr)
       if isinstance(val, (int, float, str, bool)):
          print("%s.%s=%s" % (name,attr,val))
       else:
          dump( val, name + "." + attr, level+1)

print(60*"-")
dump(bpy.data,"bpy.data")
The swizzle properties Vector.xyz return a new instance of Vector.

I.e. using a python property

class MyVectorClass(tuple):
    def get_xxx(self):
        return MyVectorClass((self[0],)*3)
    xxx = property(fget=get_xxx)

v = MyVectorClass((1.0, 2.0))
v.xxx.xxx.xxx
#equivalent to
v.get_xxx().get_xxx().get_xxx()


I would suggest Vector.to_tuple. That is everything you need.

BTW: To properly check for the type you should use isinstance

import mathutils

if isinstance(v, mathutils.Vector):
    t = v.to_tuple()