[Bf-blender-cvs] [c8edc458d13] master: PyDoc: support building full API docs on macOS & WIN32

Campbell Barton noreply at git.blender.org
Wed May 18 09:07:36 CEST 2022


Commit: c8edc458d13c0483907d0fe6f44f6e2887263b57
Author: Campbell Barton
Date:   Wed May 18 16:59:16 2022 +1000
Branches: master
https://developer.blender.org/rBc8edc458d13c0483907d0fe6f44f6e2887263b57

PyDoc: support building full API docs on macOS & WIN32

Accessing context members depended on `ctypes` to access symbols
which were hidden for macOS & WIN32.

Add an API call that doesn't require the symbols to be exported.

This allows most symbols to be hidden on Linux, see D14971.

===================================================================

M	doc/python_api/sphinx_doc_gen.py
M	source/blender/python/intern/bpy.c

===================================================================

diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index eba12b75b63..1c52bb3e57d 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -1200,34 +1200,18 @@ def pycontext2sphinx(basepath):
     del write_contex_cls
     # end
 
-    # nasty, get strings directly from Blender because there is no other way to get it
-    import ctypes
-
-    context_strings = (
-        "screen_context_dir",
-        "view3d_context_dir",
-        "buttons_context_dir",
-        "image_context_dir",
-        "node_context_dir",
-        "text_context_dir",
-        "clip_context_dir",
-        "sequencer_context_dir",
-        "file_context_dir",
-    )
+    # Internal API call only intended to be used to extract context members.
+    from _bpy import context_members
+    context_member_map = context_members()
+    del context_members
 
     # Track unique for `context_strings` to validate `context_type_map`.
     unique_context_strings = set()
-    blend_cdll = ctypes.CDLL("")
-    for ctx_str in context_strings:
+    for ctx_str, ctx_members in sorted(context_member_map.items()):
         subsection = "%s Context" % ctx_str.split("_")[0].title()
         fw("\n%s\n%s\n\n" % (subsection, (len(subsection) * '-')))
-
-        attr = ctypes.addressof(getattr(blend_cdll, ctx_str))
-        c_char_p_p = ctypes.POINTER(ctypes.c_char_p)
-        char_array = c_char_p_p.from_address(attr)
         i = 0
-        while char_array[i] is not None:
-            member = ctypes.string_at(char_array[i]).decode(encoding="ascii")
+        for member in ctx_members:
             unique_all_len = len(unique)
             unique.add(member)
             member_visited = unique_all_len == len(unique)
@@ -2167,10 +2151,7 @@ def rna2sphinx(basepath):
 
     # context
     if "bpy.context" not in EXCLUDE_MODULES:
-        # one of a kind, context doc (uses ctypes to extract info!)
-        # doesn't work on mac and windows
-        if PLATFORM not in {"darwin", "windows"}:
-            pycontext2sphinx(basepath)
+        pycontext2sphinx(basepath)
 
     # internal modules
     write_rst_bpy(basepath)                 # bpy, disabled by default
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 748a501ef76..9d8602d51bd 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -400,6 +400,62 @@ static PyObject *bpy_unescape_identifier(PyObject *UNUSED(self), PyObject *value
   return value_unescape;
 }
 
+/**
+ * \note only exposed for generating documentation, see: `doc/python_api/sphinx_doc_gen.py`.
+ */
+PyDoc_STRVAR(
+    bpy_context_members_doc,
+    ".. function:: context_members()\n"
+    "\n"
+    "   :return: A dict where the key is the context and the value is a tuple of it's members.\n"
+    "   :rtype: dict\n");
+static PyObject *bpy_context_members(PyObject *UNUSED(self))
+{
+  extern const char *buttons_context_dir[];
+  extern const char *clip_context_dir[];
+  extern const char *file_context_dir[];
+  extern const char *image_context_dir[];
+  extern const char *node_context_dir[];
+  extern const char *screen_context_dir[];
+  extern const char *sequencer_context_dir[];
+  extern const char *text_context_dir[];
+  extern const char *view3d_context_dir[];
+
+  struct {
+    const char *name;
+    const char **dir;
+  } context_members_all[] = {
+      {"buttons", buttons_context_dir},
+      {"clip", clip_context_dir},
+      {"file", file_context_dir},
+      {"image", image_context_dir},
+      {"node", node_context_dir},
+      {"screen", screen_context_dir},
+      {"sequencer", sequencer_context_dir},
+      {"text", text_context_dir},
+      {"view3d", view3d_context_dir},
+  };
+
+  PyObject *result = _PyDict_NewPresized(ARRAY_SIZE(context_members_all));
+  for (int context_index = 0; context_index < ARRAY_SIZE(context_members_all); context_index++) {
+    const char *name = context_members_all[context_index].name;
+    const char **dir = context_members_all[context_index].dir;
+    int i;
+    for (i = 0; dir[i]; i++) {
+      /* Pass. */
+    }
+    PyObject *members = PyTuple_New(i);
+    for (i = 0; dir[i]; i++) {
+      PyTuple_SET_ITEM(members, i, PyUnicode_FromString(dir[i]));
+    }
+    PyDict_SetItemString(result, name, members);
+    Py_DECREF(members);
+  }
+  BLI_assert(PyDict_GET_SIZE(result) == ARRAY_SIZE(context_members_all));
+
+  return result;
+}
+
 static PyMethodDef meth_bpy_script_paths = {
     "script_paths",
     (PyCFunction)bpy_script_paths,
@@ -448,6 +504,12 @@ static PyMethodDef meth_bpy_unescape_identifier = {
     METH_O,
     bpy_unescape_identifier_doc,
 };
+static PyMethodDef meth_bpy_context_members = {
+    "context_members",
+    (PyCFunction)bpy_context_members,
+    METH_NOARGS,
+    bpy_context_members_doc,
+};
 
 static PyObject *bpy_import_test(const char *modname)
 {
@@ -551,6 +613,9 @@ void BPy_init_modules(struct bContext *C)
                      (PyObject *)PyCFunction_New(&meth_bpy_unescape_identifier, NULL));
   PyModule_AddObject(
       mod, meth_bpy_flip_name.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_flip_name, NULL));
+  PyModule_AddObject(mod,
+                     meth_bpy_context_members.ml_name,
+                     (PyObject *)PyCFunction_New(&meth_bpy_context_members, NULL));
 
   /* register funcs (bpy_rna.c) */
   PyModule_AddObject(mod,



More information about the Bf-blender-cvs mailing list