[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55829] trunk/blender/source/blender: fix [#34870] bmesh.ops.* parameter lists and descriptions don' t show in PyConsole on auto-complete

Campbell Barton ideasman42 at gmail.com
Fri Apr 5 21:58:18 CEST 2013


Revision: 55829
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55829
Author:   campbellbarton
Date:     2013-04-05 19:58:18 +0000 (Fri, 05 Apr 2013)
Log Message:
-----------
fix [#34870] bmesh.ops.* parameter lists and descriptions don't show in PyConsole on auto-complete

more a feature request then a bug but nice to have __doc__ on bmesh operators.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_operator_api.h
    trunk/blender/source/blender/bmesh/intern/bmesh_operators.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_ops.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_operator_api.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_operator_api.h	2013-04-05 19:34:26 UTC (rev 55828)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_operator_api.h	2013-04-05 19:58:18 UTC (rev 55829)
@@ -482,6 +482,8 @@
 
 extern const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES];
 
+int BMO_opcode_from_opname(const char *opname);
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_operators.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_operators.c	2013-04-05 19:34:26 UTC (rev 55828)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_operators.c	2013-04-05 19:58:18 UTC (rev 55829)
@@ -47,7 +47,6 @@
 static void bmo_flag_layer_clear(BMesh *bm);
 static int bmo_name_to_slotcode(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
 static int bmo_name_to_slotcode_check(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
-static int bmo_opname_to_opcode(const char *opname);
 
 static const char *bmo_error_messages[] = {
 	NULL,
@@ -145,7 +144,7 @@
  */
 void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
 {
-	int opcode = bmo_opname_to_opcode(opname);
+	int opcode = BMO_opcode_from_opname(opname);
 
 #ifdef DEBUG
 	BM_ELEM_INDEX_VALIDATE(bm, "pre bmo", opname);
@@ -1522,20 +1521,27 @@
 	return i;
 }
 
-static int bmo_opname_to_opcode(const char *opname)
+int BMO_opcode_from_opname(const char *opname)
 {
-	int i;
 
-	for (i = 0; i < bmo_opdefines_total; i++) {
-		if (STREQ(opname, bmo_opdefines[i]->opname)) {
+	const unsigned int tot = bmo_opdefines_total;
+	unsigned int i;
+	for (i = 0; i < tot; i++) {
+		if (STREQ(bmo_opdefines[i]->opname, opname)) {
 			return i;
 		}
 	}
-
-	fprintf(stderr, "%s: could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, opname);
 	return -1;
 }
 
+static int BMO_opcode_from_opname_check(const char *opname)
+{
+	int i = BMO_opcode_from_opname(opname);
+	if (i == -1)
+		fprintf(stderr, "%s: could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, opname);
+	return i;
+}
+
 /**
  * \brief Format Strings for #BMOperator Initialization.
  *
@@ -1628,10 +1634,11 @@
 
 	fmt += i + (noslot ? 0 : 1);
 	
-	i = bmo_opname_to_opcode(opname);
+	i = BMO_opcode_from_opname_check(opname);
 
 	if (i == -1) {
 		MEM_freeN(ofmt);
+		BLI_assert(0);
 		return false;
 	}
 

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_ops.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_ops.c	2013-04-05 19:34:26 UTC (rev 55828)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_ops.c	2013-04-05 19:58:18 UTC (rev 55829)
@@ -33,6 +33,7 @@
 #include <Python.h>
 
 #include "BLI_utildefines.h"
+#include "BLI_dynstr.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -68,7 +69,77 @@
 }
 
 
+/* methods
+ * ======= */
 
+
+/* __doc__
+ * ------- */
+
+static char *bmp_slots_as_args(const BMOSlotType slot_types[BMO_OP_MAX_SLOTS], const bool is_out)
+{
+	DynStr *dyn_str = BLI_dynstr_new();
+	char *ret;
+
+	int i = 0;
+
+	while (*slot_types[i].name) {
+		/* cut off '.out' by using a string size arg */
+		const int name_len = is_out ?
+		        (strchr(slot_types[i].name, '.') - slot_types[i].name) :
+		        sizeof(slot_types[i].name);
+		const char *value = "<Unknown>";
+		switch (slot_types[i].type) {
+			case BMO_OP_SLOT_BOOL:          value = "False"; break;
+			case BMO_OP_SLOT_INT:           value = "0"; break;
+			case BMO_OP_SLOT_FLT:           value = "0.0"; break;
+			case BMO_OP_SLOT_PTR:           value = "None"; break;
+			case BMO_OP_SLOT_MAT:           value = "Matrix()"; break;
+			case BMO_OP_SLOT_VEC:           value = "Vector()"; break;
+			case BMO_OP_SLOT_ELEMENT_BUF:   value =
+			     (slot_types[i].subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) ? "None" : "[]"; break;
+			case BMO_OP_SLOT_MAPPING:       value = "{}"; break;
+		}
+		BLI_dynstr_appendf(dyn_str, i ? ", %.*s=%s" : "%.*s=%s", name_len, slot_types[i].name, value);
+		i++;
+	};
+
+	ret = BLI_dynstr_get_cstring(dyn_str);
+	BLI_dynstr_free(dyn_str);
+	return ret;
+}
+
+static PyObject *bpy_bmesh_op_doc_get(BPy_BMeshOpFunc *self, void *UNUSED(closure))
+{
+	PyObject *ret;
+	char *slot_in;
+	char *slot_out;
+	int i;
+
+	i = BMO_opcode_from_opname(self->opname);
+
+	slot_in  = bmp_slots_as_args(bmo_opdefines[i]->slot_types_in, false);
+	slot_out = bmp_slots_as_args(bmo_opdefines[i]->slot_types_out, true);
+
+	ret = PyUnicode_FromFormat("%.200s bmesh.ops.%.200s(bmesh, %s)\n  -> dict(%s)",
+	                           Py_TYPE(self)->tp_name,
+	                           self->opname, slot_in, slot_out);
+
+	MEM_freeN(slot_in);
+	MEM_freeN(slot_out);
+
+	return ret;
+}
+
+static PyGetSetDef bpy_bmesh_op_getseters[] = {
+	{(char *)"__doc__", (getter)bpy_bmesh_op_doc_get, (setter)NULL, NULL, NULL},
+	{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+
+/* Types
+ * ===== */
+
 PyTypeObject bmesh_op_Type = {
 	PyVarObject_HEAD_INIT(NULL, 0)
 	"BMeshOpFunc",              /* tp_name */
@@ -126,7 +197,7 @@
 	/*** Attribute descriptor and subclassing stuff ***/
 	NULL,                       /* struct PyMethodDef *tp_methods; */
 	NULL,                       /* struct PyMemberDef *tp_members; */
-	NULL,                       /* struct PyGetSetDef *tp_getset; */
+	bpy_bmesh_op_getseters,     /* struct PyGetSetDef *tp_getset; */
 	NULL,                       /* struct _typeobject *tp_base; */
 	NULL,                       /* PyObject *tp_dict; */
 	NULL,                       /* descrgetfunc tp_descr_get; */
@@ -154,20 +225,17 @@
 
 static PyObject *bpy_bmesh_ops_fakemod_getattro(PyObject *UNUSED(self), PyObject *pyname)
 {
-	const unsigned int tot = bmo_opdefines_total;
-	unsigned int i;
 	const char *opname = _PyUnicode_AsString(pyname);
 
-	for (i = 0; i < tot; i++) {
-		if (STREQ(bmo_opdefines[i]->opname, opname)) {
-			return bpy_bmesh_op_CreatePyObject(opname);
-		}
+	if (BMO_opcode_from_opname(opname) != -1) {
+		return bpy_bmesh_op_CreatePyObject(opname);
 	}
-
-	PyErr_Format(PyExc_AttributeError,
-	             "BMeshOpsModule: operator \"%.200s\" doesn't exist",
-	             opname);
-	return NULL;
+	else {
+		PyErr_Format(PyExc_AttributeError,
+		             "BMeshOpsModule: operator \"%.200s\" doesn't exist",
+		             opname);
+		return NULL;
+	}
 }
 
 static PyObject *bpy_bmesh_ops_fakemod_dir(PyObject *UNUSED(self))




More information about the Bf-blender-cvs mailing list