rna/py/reference doc improvements..

- vectors now respect min/max settings.
- keyframing and adding drivers raises an error in an index is set on a non array, keyframing raises an error if it fails.

reference docs...
- added docstrings for remaining python bpy_struct functions
- added fake class for docs, bpy_struct, which is the base class of everything in bpy.types
- improved inherictance references for struct classes, include bpy_struct members.
This commit is contained in:
Campbell Barton 2010-04-10 18:35:50 +00:00
parent c939331a6c
commit 6e3920e8fa
3 changed files with 301 additions and 120 deletions

@ -25,6 +25,7 @@ import bpy
# use to strip python paths # use to strip python paths
script_paths = bpy.utils.script_paths() script_paths = bpy.utils.script_paths()
_FAKE_STRUCT_SUBCLASS = True
def _get_direct_attr(rna_type, attr): def _get_direct_attr(rna_type, attr):
props = getattr(rna_type, attr) props = getattr(rna_type, attr)
@ -44,6 +45,19 @@ def get_direct_properties(rna_type):
def get_direct_functions(rna_type): def get_direct_functions(rna_type):
return _get_direct_attr(rna_type, "functions") return _get_direct_attr(rna_type, "functions")
def rna_id_ignore(rna_id):
if rna_id == "rna_type":
return True
if "_OT_" in rna_id:
return True
if "_MT_" in rna_id:
return True
if "_PT_" in rna_id:
return True
if "_HT_" in rna_id:
return True
return False
def range_str(val): def range_str(val):
if val < -10000000: if val < -10000000:
@ -135,17 +149,17 @@ class InfoStructRNA:
def __repr__(self): def __repr__(self):
txt = '' txt = ""
txt += self.identifier txt += self.identifier
if self.base: if self.base:
txt += '(%s)' % self.base.identifier txt += "(%s)" % self.base.identifier
txt += ': ' + self.description + '\n' txt += ": " + self.description + "\n"
for prop in self.properties: for prop in self.properties:
txt += prop.__repr__() + '\n' txt += prop.__repr__() + "\n"
for func in self.functions: for func in self.functions:
txt += func.__repr__() + '\n' txt += func.__repr__() + "\n"
return txt return txt
@ -377,7 +391,6 @@ def GetInfoFunctionRNA(bl_rna, parent_id):
def GetInfoOperatorRNA(bl_rna): def GetInfoOperatorRNA(bl_rna):
return _GetInfoRNA(bl_rna, InfoOperatorRNA) return _GetInfoRNA(bl_rna, InfoOperatorRNA)
def BuildRNAInfo(): def BuildRNAInfo():
# Use for faster lookups # Use for faster lookups
# use rna_struct.identifier as the key for each dict # use rna_struct.identifier as the key for each dict
@ -387,19 +400,6 @@ def BuildRNAInfo():
rna_references_dict = {} # store a list of rna path strings that reference this type rna_references_dict = {} # store a list of rna path strings that reference this type
# rna_functions_dict = {} # store all functions directly in this type (not inherited) # rna_functions_dict = {} # store all functions directly in this type (not inherited)
def rna_id_ignore(rna_id):
if rna_id == "rna_type":
return True
if "_OT_" in rna_id:
return True
if "_MT_" in rna_id:
return True
if "_PT_" in rna_id:
return True
if "_HT_" in rna_id:
return True
return False
def full_rna_struct_path(rna_struct): def full_rna_struct_path(rna_struct):
''' '''

@ -50,6 +50,8 @@ GetSetDescriptorType = type(int.real)
EXAMPLE_SET = set() EXAMPLE_SET = set()
EXAMPLE_SET_USED = set() EXAMPLE_SET_USED = set()
_BPY_STRUCT_FAKE = "bpy_struct"
def range_str(val): def range_str(val):
if val < -10000000: return '-inf' if val < -10000000: return '-inf'
if val > 10000000: return 'inf' if val > 10000000: return 'inf'
@ -122,6 +124,23 @@ def pyfunc2sphinx(ident, fw, identifier, py_func, is_class=True):
write_indented_lines(ident + " ", fw, py_func.__doc__.strip()) write_indented_lines(ident + " ", fw, py_func.__doc__.strip())
fw("\n") fw("\n")
def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):
doc = descr.__doc__
if not doc:
doc = "Undocumented"
if type(descr) == GetSetDescriptorType:
fw(ident + ".. attribute:: %s\n\n" % identifier)
write_indented_lines(ident, fw, doc, False)
elif type(descr) == MethodDescriptorType: # GetSetDescriptorType, GetSetDescriptorType's are not documented yet
write_indented_lines(ident, fw, doc, False)
else:
raise TypeError("type was not GetSetDescriptorType or MethodDescriptorType")
write_example_ref(ident, fw, module_name + "." + type_name + "." + identifier)
fw("\n")
def py_c_func2sphinx(ident, fw, identifier, py_func, is_class=True): def py_c_func2sphinx(ident, fw, identifier, py_func, is_class=True):
''' '''
c defined function to sphinx. c defined function to sphinx.
@ -169,10 +188,10 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
# write members of the module # write members of the module
# only tested with PyStructs which are not exactly modules # only tested with PyStructs which are not exactly modules
for attribute, descr in sorted(type(module).__dict__.items()): for key, descr in sorted(type(module).__dict__.items()):
if type(descr) == types.MemberDescriptorType: if type(descr) == types.MemberDescriptorType:
if descr.__doc__: if descr.__doc__:
fw(".. data:: %s\n\n" % attribute) fw(".. data:: %s\n\n" % key)
write_indented_lines(" ", fw, descr.__doc__, False) write_indented_lines(" ", fw, descr.__doc__, False)
fw("\n") fw("\n")
@ -202,37 +221,26 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
else: else:
print("\tnot documenting %s.%s" % (module_name, attribute)) print("\tnot documenting %s.%s" % (module_name, attribute))
# TODO, more types... # TODO, more types...
# write collected classes now # write collected classes now
for (attribute, value) in classes: for (type_name, value) in classes:
# May need to be its own function # May need to be its own function
fw(".. class:: %s\n\n" % attribute) fw(".. class:: %s\n\n" % type_name)
if value.__doc__: if value.__doc__:
write_indented_lines(" ", fw, value.__doc__, False) write_indented_lines(" ", fw, value.__doc__, False)
fw("\n") fw("\n")
write_example_ref(" ", fw, module_name + "." + attribute) write_example_ref(" ", fw, module_name + "." + type_name)
for key in sorted(value.__dict__.keys()): descr_items = [(key, descr) for key, descr in sorted(value.__dict__.items()) if not key.startswith("__")]
if key.startswith("__"):
continue
descr = value.__dict__[key]
if type(descr) == GetSetDescriptorType:
if descr.__doc__:
fw(" .. attribute:: %s\n\n" % key)
write_indented_lines(" ", fw, descr.__doc__, False)
write_example_ref(" ", fw, module_name + "." + attribute + "." + key)
fw("\n")
for key in sorted(value.__dict__.keys()): for key, descr in descr_items:
if key.startswith("__"):
continue
descr = value.__dict__[key]
if type(descr) == MethodDescriptorType: # GetSetDescriptorType, GetSetDescriptorType's are not documented yet if type(descr) == MethodDescriptorType: # GetSetDescriptorType, GetSetDescriptorType's are not documented yet
if descr.__doc__: py_descr2sphinx(" ", fw, descr, module_name, type_name, key)
write_indented_lines(" ", fw, descr.__doc__, False)
write_example_ref(" ", fw, module_name + "." + attribute + "." + key) for key, descr in descr_items:
fw("\n") if type(descr) == GetSetDescriptorType:
py_descr2sphinx(" ", fw, descr, module_name, type_name, key)
fw("\n\n") fw("\n\n")
file.close() file.close()
@ -400,8 +408,14 @@ def rna2sphinx(BASEPATH):
file = open(filepath, "w") file = open(filepath, "w")
fw = file.write fw = file.write
if struct.base: base_id = getattr(struct.base, "identifier", "")
title = "%s(%s)" % (struct.identifier, struct.base.identifier)
if _BPY_STRUCT_FAKE:
if not base_id:
base_id = _BPY_STRUCT_FAKE
if base_id:
title = "%s(%s)" % (struct.identifier, base_id)
else: else:
title = struct.identifier title = struct.identifier
@ -409,26 +423,34 @@ def rna2sphinx(BASEPATH):
fw(".. module:: bpy.types\n\n") fw(".. module:: bpy.types\n\n")
bases = struct.get_bases() base_ids = [base.identifier for base in struct.get_bases()]
if bases:
if len(bases) > 1: if _BPY_STRUCT_FAKE:
base_ids.append(_BPY_STRUCT_FAKE)
base_ids.reverse()
if base_ids:
if len(base_ids) > 1:
fw("base classes --- ") fw("base classes --- ")
else: else:
fw("base class --- ") fw("base class --- ")
fw(", ".join([(":class:`%s`" % base.identifier) for base in reversed(bases)])) fw(", ".join([(":class:`%s`" % base_id) for base_id in base_ids]))
fw("\n\n") fw("\n\n")
subclasses = [s for s in structs.values() if s.base is struct] subclass_ids = [s.identifier for s in structs.values() if s.base is struct if not rna_info.rna_id_ignore(s.identifier)]
if subclass_ids:
fw("subclasses --- \n" + ", ".join([(":class:`%s`" % s) for s in subclass_ids]) + "\n\n")
if subclasses: base_id = getattr(struct.base, "identifier", "")
fw("subclasses --- \n")
fw(", ".join([(":class:`%s`" % s.identifier) for s in subclasses])) if _BPY_STRUCT_FAKE:
fw("\n\n") if not base_id:
base_id = _BPY_STRUCT_FAKE
if base_id:
if struct.base: fw(".. class:: %s(%s)\n\n" % (struct.identifier, base_id))
fw(".. class:: %s(%s)\n\n" % (struct.identifier, struct.base.identifier))
else: else:
fw(".. class:: %s\n\n" % struct.identifier) fw(".. class:: %s\n\n" % struct.identifier)
@ -479,28 +501,31 @@ def rna2sphinx(BASEPATH):
pyfunc2sphinx(" ", fw, identifier, py_func, is_class=True) pyfunc2sphinx(" ", fw, identifier, py_func, is_class=True)
del py_funcs, py_func del py_funcs, py_func
# c/python methods, only for the base class
if struct.identifier == "Struct":
for attribute, descr in sorted(bpy.types.Struct.__bases__[0].__dict__.items()):
if type(descr) == MethodDescriptorType: # GetSetDescriptorType, GetSetDescriptorType's are not documented yet
if descr.__doc__:
write_indented_lines(" ", fw, descr.__doc__, False)
write_example_ref(" ", fw, struct.identifier + "." + attribute)
fw("\n")
lines = [] lines = []
if struct.base: if struct.base or _BPY_STRUCT_FAKE:
bases = list(reversed(struct.get_bases())) bases = list(reversed(struct.get_bases()))
# props # props
lines[:] = [] lines[:] = []
if _BPY_STRUCT_FAKE:
descr_items = [(key, descr) for key, descr in sorted(bpy.types.Struct.__bases__[0].__dict__.items()) if not key.startswith("__")]
if _BPY_STRUCT_FAKE:
for key, descr in descr_items:
if type(descr) == GetSetDescriptorType:
lines.append("* :class:`%s.%s`\n" % (_BPY_STRUCT_FAKE, key))
for base in bases: for base in bases:
for prop in base.properties: for prop in base.properties:
lines.append("* :class:`%s.%s`\n" % (base.identifier, prop.identifier)) lines.append("* :class:`%s.%s`\n" % (base.identifier, prop.identifier))
for identifier, py_prop in base.get_py_properties(): for identifier, py_prop in base.get_py_properties():
lines.append("* :class:`%s.%s`\n" % (base.identifier, identifier)) lines.append("* :class:`%s.%s`\n" % (base.identifier, identifier))
for identifier, py_prop in base.get_py_properties():
lines.append("* :class:`%s.%s`\n" % (base.identifier, identifier))
if lines: if lines:
fw(".. rubric:: Inherited Properties\n\n") fw(".. rubric:: Inherited Properties\n\n")
@ -511,6 +536,12 @@ def rna2sphinx(BASEPATH):
# funcs # funcs
lines[:] = [] lines[:] = []
if _BPY_STRUCT_FAKE:
for key, descr in descr_items:
if type(descr) == MethodDescriptorType:
lines.append("* :class:`%s.%s`\n" % (_BPY_STRUCT_FAKE, key))
for base in bases: for base in bases:
for func in base.functions: for func in base.functions:
lines.append("* :class:`%s.%s`\n" % (base.identifier, func.identifier)) lines.append("* :class:`%s.%s`\n" % (base.identifier, func.identifier))
@ -543,6 +574,38 @@ def rna2sphinx(BASEPATH):
if "_OT_" in struct.identifier: if "_OT_" in struct.identifier:
continue continue
write_struct(struct) write_struct(struct)
# special case, bpy_struct
if _BPY_STRUCT_FAKE:
filepath = os.path.join(BASEPATH, "bpy.types.%s.rst" % _BPY_STRUCT_FAKE)
file = open(filepath, "w")
fw = file.write
fw("%s\n" % _BPY_STRUCT_FAKE)
fw("=" * len(_BPY_STRUCT_FAKE) + "\n")
fw("\n")
fw(".. module:: bpy.types\n")
fw("\n")
subclass_ids = [s.identifier for s in structs.values() if s.base is None if not rna_info.rna_id_ignore(s.identifier)]
if subclass_ids:
fw("subclasses --- \n" + ", ".join([(":class:`%s`" % s) for s in sorted(subclass_ids)]) + "\n\n")
fw(".. class:: %s\n" % _BPY_STRUCT_FAKE)
fw("\n")
fw(" built-in base class for all classes in bpy.types, note that bpy.types.%s is not actually available from within blender, it only exists for the purpose of documentation.\n" % _BPY_STRUCT_FAKE)
fw("\n")
descr_items = [(key, descr) for key, descr in sorted(bpy.types.Struct.__bases__[0].__dict__.items()) if not key.startswith("__")]
for key, descr in descr_items:
if type(descr) == MethodDescriptorType: # GetSetDescriptorType, GetSetDescriptorType's are not documented yet
py_descr2sphinx(" ", fw, descr, "bpy.types", _BPY_STRUCT_FAKE, key)
for key, descr in descr_items:
if type(descr) == GetSetDescriptorType:
py_descr2sphinx(" ", fw, descr, "bpy.types", _BPY_STRUCT_FAKE, key)
# oeprators # oeprators
def write_ops(): def write_ops():
@ -563,7 +626,7 @@ def rna2sphinx(BASEPATH):
fw(".. module:: bpy.ops.%s\n\n" % op.module_name) fw(".. module:: bpy.ops.%s\n\n" % op.module_name)
last_mod = op.module_name last_mod = op.module_name
args_str = ", ".join([prop.get_arg_default(force=True) for prop in op.args]) args_str = ", ".join([prop.get_arg_default(force=True) for prop in op.args])
fw(".. function:: %s(%s)\n\n" % (op.func_name, args_str)) fw(".. function:: %s(%s)\n\n" % (op.func_name, args_str))
if op.description: if op.description:

@ -1,4 +1,3 @@
/** /**
* $Id$ * $Id$
* *
@ -84,9 +83,19 @@ static int mathutils_rna_vector_get(BPy_PropertyRNA *self, int subtype, float *v
static int mathutils_rna_vector_set(BPy_PropertyRNA *self, int subtype, float *vec_to) static int mathutils_rna_vector_set(BPy_PropertyRNA *self, int subtype, float *vec_to)
{ {
float min, max;
if(self->prop==NULL) if(self->prop==NULL)
return 0; return 0;
/* TODO, clamp */
RNA_property_float_range(&self->ptr, self->prop, &min, &max);
if(min != FLT_MIN || max != FLT_MAX) {
int i, len= RNA_property_array_length(&self->ptr, self->prop);
for(i=0; i<len; i++) {
CLAMP(vec_to[i], min, max);
}
}
RNA_property_float_set_array(&self->ptr, self->prop, vec_to); RNA_property_float_set_array(&self->ptr, self->prop, vec_to);
RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); RNA_property_update(BPy_GetContext(), &self->ptr, self->prop);
return 1; return 1;
@ -1613,6 +1622,16 @@ static PyMappingMethods pyrna_struct_as_mapping = {
( objobjargproc ) pyrna_struct_ass_subscript, /* mp_ass_subscript */ ( objobjargproc ) pyrna_struct_ass_subscript, /* mp_ass_subscript */
}; };
static char pyrna_struct_keys_doc[] =
".. method:: keys()\n"
"\n"
" Returns the keys of this objects custom properties (matches pythons dictionary function of the same name).\n"
"\n"
" :return: custom property keys.\n"
" :rtype: list of strings\n"
"\n"
" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self) static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
{ {
IDProperty *group; IDProperty *group;
@ -1630,6 +1649,16 @@ static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
return BPy_Wrap_GetKeys(group); return BPy_Wrap_GetKeys(group);
} }
static char pyrna_struct_items_doc[] =
".. method:: items()\n"
"\n"
" Returns the items of this objects custom properties (matches pythons dictionary function of the same name).\n"
"\n"
" :return: custom property key, value pairs.\n"
" :rtype: list of key, value tuples\n"
"\n"
" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
static PyObject *pyrna_struct_items(BPy_PropertyRNA *self) static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
{ {
IDProperty *group; IDProperty *group;
@ -1647,6 +1676,15 @@ static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
return BPy_Wrap_GetItems(self->ptr.id.data, group); return BPy_Wrap_GetItems(self->ptr.id.data, group);
} }
static char pyrna_struct_values_doc[] =
".. method:: values()\n"
"\n"
" Returns the values of this objects custom properties (matches pythons dictionary function of the same name).\n"
"\n"
" :return: custom property values.\n"
" :rtype: list\n"
"\n"
" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
static PyObject *pyrna_struct_values(BPy_PropertyRNA *self) static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
{ {
@ -1671,7 +1709,6 @@ static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, char *er
{ {
char *path; char *path;
PropertyRNA *prop; PropertyRNA *prop;
int array_len;
if (!PyArg_ParseTuple(args, "s|ifs", &path, index, cfra, group_name)) { if (!PyArg_ParseTuple(args, "s|ifs", &path, index, cfra, group_name)) {
PyErr_Format(PyExc_TypeError, "%.200s expected a string and optionally an int, float, and string arguments", error_prefix); PyErr_Format(PyExc_TypeError, "%.200s expected a string and optionally an int, float, and string arguments", error_prefix);
@ -1691,10 +1728,27 @@ static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, char *er
} }
if (!RNA_property_animateable(ptr, prop)) { if (!RNA_property_animateable(ptr, prop)) {
PyErr_Format( PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path); PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
return -1; return -1;
} }
if(RNA_property_array_check(ptr, prop) == 0) {
if((*index) == -1) {
*index= 0;
}
else {
PyErr_Format(PyExc_TypeError, "%.200s index %d was given while property \"%s\" is not an array", error_prefix, *index, path);
return -1;
}
}
else {
int array_len= RNA_property_array_length(ptr, prop);
if((*index) < -1 || (*index) >= array_len) {
PyErr_Format( PyExc_TypeError, "%.200s index out of range \"%s\", given %d, array length is %d", error_prefix, path, *index, array_len);
return -1;
}
}
*path_full= RNA_path_from_ID_to_property(ptr, prop); *path_full= RNA_path_from_ID_to_property(ptr, prop);
if (*path_full==NULL) { if (*path_full==NULL) {
@ -1702,12 +1756,6 @@ static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, char *er
return -1; return -1;
} }
array_len= RNA_property_array_length(ptr, prop);
if((*index) != -1 && (*index) >= array_len) {
PyErr_Format( PyExc_TypeError, "%.200s index out of range \"%s\", given %d, array length is %d", error_prefix, path, *index, array_len);
return -1;
}
if(*cfra==FLT_MAX) if(*cfra==FLT_MAX)
*cfra= CTX_data_scene(BPy_GetContext())->r.cfra; *cfra= CTX_data_scene(BPy_GetContext())->r.cfra;
@ -1715,9 +1763,9 @@ static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, char *er
} }
static char pyrna_struct_keyframe_insert_doc[] = static char pyrna_struct_keyframe_insert_doc[] =
".. function:: keyframe_insert(path, index=-1, frame=bpy.context.scene.frame_current)\n" ".. method:: keyframe_insert(path, index=-1, frame=bpy.context.scene.frame_current)\n"
"\n" "\n"
" Returns a boolean, True if the keyframe is set.\n" " Insert a keyframe on the property given, adding fcurves and animation data when necessary.\n"
"\n" "\n"
" :arg path: path to the property to key, analogous to the fcurve's data path.\n" " :arg path: path to the property to key, analogous to the fcurve's data path.\n"
" :type path: string\n" " :type path: string\n"
@ -1725,8 +1773,10 @@ static char pyrna_struct_keyframe_insert_doc[] =
" :type index: int\n" " :type index: int\n"
" :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n" " :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
" :type frame: float\n" " :type frame: float\n"
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n" " :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str"; " :type group: str\n"
" :return: Success of keyframe insertion.\n"
" :rtype: boolean";
static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args) static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args)
{ {
@ -1747,9 +1797,9 @@ static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *arg
} }
static char pyrna_struct_keyframe_delete_doc[] = static char pyrna_struct_keyframe_delete_doc[] =
".. function:: keyframe_delete(path, index=-1, frame=bpy.context.scene.frame_current)\n" ".. method:: keyframe_delete(path, index=-1, frame=bpy.context.scene.frame_current)\n"
"\n" "\n"
" Returns a boolean, True if the keyframe is removed.\n" " Remove a keyframe from this properties fcurve.\n"
"\n" "\n"
" :arg path: path to the property to remove a key, analogous to the fcurve's data path.\n" " :arg path: path to the property to remove a key, analogous to the fcurve's data path.\n"
" :type path: string\n" " :type path: string\n"
@ -1757,8 +1807,10 @@ static char pyrna_struct_keyframe_delete_doc[] =
" :type index: int\n" " :type index: int\n"
" :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n" " :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n"
" :type frame: float\n" " :type frame: float\n"
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n" " :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str"; " :type group: str\n"
" :return: Success of keyframe deleation.\n"
" :rtype: boolean";
static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args) static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args)
{ {
@ -1779,19 +1831,21 @@ static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *arg
} }
static char pyrna_struct_driver_add_doc[] = static char pyrna_struct_driver_add_doc[] =
".. function:: driver_add(path, index=-1)\n" ".. method:: driver_add(path, index=-1)\n"
"\n" "\n"
" Returns the newly created driver or a list of drivers in the case of an array\n" " Adds driver(s) to the given property\n"
"\n" "\n"
" :arg path: path to the property to drive, analogous to the fcurve's data path.\n" " :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
" :type path: string\n" " :type path: string\n"
" :arg index: array index of the property drive. Defaults to -1 for all indicies or a single channel if the property is not an array.\n" " :arg index: array index of the property drive. Defaults to -1 for all indicies or a single channel if the property is not an array.\n"
" :type index: int"; " :type index: int\n"
" :return: The driver(s) added.\n"
" :rtype: :class:`FCurve` or list if index is -1 with an array property.";
static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args) static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
{ {
char *path, *path_full; char *path, *path_full;
int index= -1; /* default to all */ int index= -1;
PropertyRNA *prop; PropertyRNA *prop;
PyObject *ret; PyObject *ret;
@ -1814,6 +1868,23 @@ static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): property \"%s\" not animatable", path); PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): property \"%s\" not animatable", path);
return NULL; return NULL;
} }
if(RNA_property_array_check(&self->ptr, prop) == 0) {
if(index == -1) {
index= 0;
}
else {
PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): array index %d given while property \"%s\" is not an array", index, path);
return NULL;
}
}
else {
int array_len= RNA_property_array_length(&self->ptr, prop);
if(index < -1 || index >= array_len) {
PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): index out of range \"%s\", given %d, array length is %d", path, index, array_len);
return NULL;
}
}
path_full= RNA_path_from_ID_to_property(&self->ptr, prop); path_full= RNA_path_from_ID_to_property(&self->ptr, prop);
@ -1847,8 +1918,8 @@ static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
} }
} }
else { else {
ret= Py_None; PyErr_SetString(PyExc_TypeError, "bpy_struct.driver_add(): failed because of an internal error");
Py_INCREF(ret); return NULL;
} }
MEM_freeN(path_full); MEM_freeN(path_full);
@ -1856,6 +1927,14 @@ static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
return ret; return ret;
} }
static char pyrna_struct_is_property_set_doc[] =
".. method:: is_property_set(property)\n"
"\n"
" Check if a property is set, use for testing operator properties.\n"
"\n"
" :return: True when the property has been set.\n"
" :rtype: boolean";
static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args) static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
{ {
char *name; char *name;
@ -1866,6 +1945,14 @@ static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *arg
return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); return PyBool_FromLong(RNA_property_is_set(&self->ptr, name));
} }
static char pyrna_struct_is_property_hidden_doc[] =
".. method:: is_property_hidden(property)\n"
"\n"
" Check if a property is hidden.\n"
"\n"
" :return: True when the property is hidden.\n"
" :rtype: boolean";
static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args) static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
{ {
PropertyRNA *prop; PropertyRNA *prop;
@ -1882,12 +1969,9 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *
} }
static char pyrna_struct_path_resolve_doc[] = static char pyrna_struct_path_resolve_doc[] =
".. function:: path_resolve(path)\n" ".. method:: path_resolve(path)\n"
"\n" "\n"
" Returns the property from the path given or None if the property is not found.\n" " Returns the property from the path given or None if the property is not found.";
"\n"
" :arg path: path to the property.\n"
" :type path: string";
static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *value) static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *value)
{ {
@ -1907,12 +1991,14 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *value)
} }
static char pyrna_struct_path_from_id_doc[] = static char pyrna_struct_path_from_id_doc[] =
".. function:: path_from_id(property=\"\")\n" ".. method:: path_from_id(property=\"\")\n"
"\n" "\n"
" Returns the data path from the ID to this object (string).\n" " Returns the data path from the ID to this object (string).\n"
"\n" "\n"
" :arg property: Optional property name which can be used if the path is to a property of this object.\n" " :arg property: Optional property name which can be used if the path is to a property of this object.\n"
" :type property: string"; " :type property: string\n"
" :return: The path from :class:`bpy_struct.id_data` to this struct and property (when given).\n"
" :rtype: str";
static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args) static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
{ {
@ -1949,17 +2035,13 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
return ret; return ret;
} }
static PyObject *pyrna_struct_recast_type(BPy_StructRNA *self, PyObject *args)
{
PointerRNA r_ptr;
RNA_pointer_recast(&self->ptr, &r_ptr);
return pyrna_struct_CreatePyObject(&r_ptr);
}
static char pyrna_prop_path_from_id_doc[] = static char pyrna_prop_path_from_id_doc[] =
".. function:: path_from_id()\n" ".. method:: path_from_id()\n"
"\n" "\n"
" Returns the data path from the ID to this property (string)."; " Returns the data path from the ID to this property (string).\n"
"\n"
" :return: The path from :class:`bpy_struct.id_data` to this property.\n"
" :rtype: str";
static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self) static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
{ {
@ -1980,6 +2062,21 @@ static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
return ret; return ret;
} }
static char pyrna_struct_recast_type_doc[] =
".. method:: recast_type()\n"
"\n"
" Return a new instance, this is needed because types such as textures can be changed at runtime.\n"
"\n"
" :return: a new instance of this object with the type initialized again.\n"
" :rtype: subclass of :class:`bpy_struct`";
static PyObject *pyrna_struct_recast_type(BPy_StructRNA *self, PyObject *args)
{
PointerRNA r_ptr;
RNA_pointer_recast(&self->ptr, &r_ptr);
return pyrna_struct_CreatePyObject(&r_ptr);
}
static void pyrna_dir_members_py(PyObject *list, PyObject *self) static void pyrna_dir_members_py(PyObject *list, PyObject *self)
{ {
PyObject *dict; PyObject *dict;
@ -2348,7 +2445,7 @@ static PyGetSetDef pyrna_prop_getseters[] = {
#endif #endif
static PyGetSetDef pyrna_struct_getseters[] = { static PyGetSetDef pyrna_struct_getseters[] = {
{"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, "The ID data this datablock is from, (not available for all data)", NULL}, {"id_data", (getter)pyrna_struct_get_id_data, (setter)NULL, "The :class:`ID` object this datablock is from or None, (not available for all data types)", NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
}; };
@ -2425,6 +2522,18 @@ static PyObject *pyrna_prop_values(BPy_PropertyRNA *self)
return ret; return ret;
} }
static char pyrna_struct_get_doc[] =
".. method:: get(key, default=None)\n"
"\n"
" Returns the value of the custom property assigned to key or default when not found (matches pythons dictionary function of the same name).\n"
"\n"
" :arg key: The key assosiated with the custom property.\n"
" :type key: string\n"
" :arg default: Optional argument for the value to return if *key* is not found.\n"
// " :type default: Undefined\n"
"\n"
" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args) static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
{ {
IDProperty *group, *idprop; IDProperty *group, *idprop;
@ -2453,6 +2562,16 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
return def; return def;
} }
static char pyrna_struct_as_pointer_doc[] =
".. method:: as_pointer()\n"
"\n"
" Returns capsule which holds a pointer to blenders internal data\n"
"\n"
" :return: capsule with a name set from the struct type.\n"
" :rtype: PyCapsule\n"
"\n"
" .. note:: This is intended only for advanced script writers who need to pass blender data to their own C/Python modules.\n";
static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self) static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self)
{ {
if(self->ptr.data) if(self->ptr.data)
@ -2769,23 +2888,22 @@ PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self)
static struct PyMethodDef pyrna_struct_methods[] = { static struct PyMethodDef pyrna_struct_methods[] = {
/* only for PointerRNA's with ID'props */ /* only for PointerRNA's with ID'props */
{"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, NULL}, {"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, pyrna_struct_keys_doc},
{"values", (PyCFunction)pyrna_struct_values, METH_NOARGS, NULL}, {"values", (PyCFunction)pyrna_struct_values, METH_NOARGS, pyrna_struct_values_doc},
{"items", (PyCFunction)pyrna_struct_items, METH_NOARGS, NULL}, {"items", (PyCFunction)pyrna_struct_items, METH_NOARGS, pyrna_struct_items_doc},
{"get", (PyCFunction)pyrna_struct_get, METH_VARARGS, NULL}, {"get", (PyCFunction)pyrna_struct_get, METH_VARARGS, pyrna_struct_get_doc},
{"as_pointer", (PyCFunction)pyrna_struct_as_pointer, METH_NOARGS, NULL}, {"as_pointer", (PyCFunction)pyrna_struct_as_pointer, METH_NOARGS, pyrna_struct_as_pointer_doc},
/* maybe this become and ID function */
{"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS, pyrna_struct_keyframe_insert_doc}, {"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS, pyrna_struct_keyframe_insert_doc},
{"keyframe_delete", (PyCFunction)pyrna_struct_keyframe_delete, METH_VARARGS, pyrna_struct_keyframe_delete_doc}, {"keyframe_delete", (PyCFunction)pyrna_struct_keyframe_delete, METH_VARARGS, pyrna_struct_keyframe_delete_doc},
{"driver_add", (PyCFunction)pyrna_struct_driver_add, METH_VARARGS, pyrna_struct_driver_add_doc}, {"driver_add", (PyCFunction)pyrna_struct_driver_add, METH_VARARGS, pyrna_struct_driver_add_doc},
{"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, NULL}, {"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, pyrna_struct_is_property_set_doc},
{"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, NULL}, {"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, pyrna_struct_is_property_hidden_doc},
{"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_O, pyrna_struct_path_resolve_doc}, {"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_O, pyrna_struct_path_resolve_doc},
{"path_from_id", (PyCFunction)pyrna_struct_path_from_id, METH_VARARGS, pyrna_struct_path_from_id_doc}, {"path_from_id", (PyCFunction)pyrna_struct_path_from_id, METH_VARARGS, pyrna_struct_path_from_id_doc},
{"recast_type", (PyCFunction)pyrna_struct_recast_type, METH_NOARGS, NULL}, {"recast_type", (PyCFunction)pyrna_struct_recast_type, METH_NOARGS, pyrna_struct_recast_type_doc},
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL}, {"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
/* experemental */ /* experemental */