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))

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to