[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35076] trunk/blender/source/blender/ python/intern/bpy_interface.c: blender as module - workaround for not knowing __file__ when the module is initialized .

Campbell Barton ideasman42 at gmail.com
Tue Feb 22 15:19:09 CET 2011


Revision: 35076
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35076
Author:   campbellbarton
Date:     2011-02-22 14:19:09 +0000 (Tue, 22 Feb 2011)
Log Message:
-----------
blender as module - workaround for not knowing __file__ when the module is initialized.

Modified Paths:
--------------
    trunk/blender/source/blender/python/intern/bpy_interface.c

Modified: trunk/blender/source/blender/python/intern/bpy_interface.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_interface.c	2011-02-22 14:06:28 UTC (rev 35075)
+++ trunk/blender/source/blender/python/intern/bpy_interface.c	2011-02-22 14:19:09 UTC (rev 35076)
@@ -702,41 +702,84 @@
 	NULL,  /* m_free */
 };	
 
-PyMODINIT_FUNC
-PyInit_bpy(void)
+typedef struct {
+    PyObject_HEAD
+    /* Type-specific fields go here. */
+	PyObject *mod;
+} dealloc_obj;
+
+/* call once __file__ is set */
+void bpy_module_delay_init(PyObject *bpy_proxy)
 {
-	int argc= 1;
-	char *argv[2]={NULL, NULL};
+	const int argc= 1;
+	const char *argv[2];
 
-	/* give the CWD as the first arg, blender uses */
-	char path[240]= "";
-	BLI_getwdN(path, sizeof(path));
-	BLI_join_dirfile(path, sizeof(path), path, "bpy");
-	argv[0]= path;
-	/* done with cwd */
+	const char *filename_rel= PyModule_GetFilename(bpy_proxy); /* can be relative */
+	char filename_abs[1024];
 
+	BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs));
+	BLI_path_cwd(filename_abs);
+	
+	argv[0]= filename_abs;
+	argv[1]= NULL;
+	
+	// printf("module found %s\n", argv[0]);
+
 	main_python(argc, argv);
 
 	/* initialized in BPy_init_modules() */
-	if(bpy_package_py) {
-		/* Problem:
-		 * 1) this init function is expected to have a private member defined - 'md_def'
-		 *    but this is only set for C defined modules (not py packages)
-		 *    so we cant return 'bpy_package_py' as is.
-		 *
-		 * 2) there is a 'bpy' C module for python to load which is basically all of blender,
-		 *    and there is scripts/bpy/__init__.py, 
-		 *    we may end up having to rename this module so there is no naming conflict here eg:
-		 *    'from blender import bpy' */
-		PyObject *bpy_proxy= PyModule_Create(&bpy_proxy_def);
-		PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py));
-		return bpy_proxy;
-	}
-	else {
-		PyErr_SetString(PyExc_RuntimeError, "could not import internal bpy package");
-		return NULL;
-	}
+	PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py));
+}
+
+static void dealloc_obj_dealloc(PyObject *self);
+
+static PyTypeObject dealloc_obj_Type = {{{0}}};
+
+/* use our own dealloc so we can free a property if we use one */
+static void dealloc_obj_dealloc(PyObject *self)
+{
+	bpy_module_delay_init(((dealloc_obj *)self)->mod);
+
+	/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
+	dealloc_obj_Type.tp_free(self);
+}
+
+PyMODINIT_FUNC
+PyInit_bpy(void)
+{
+	PyObject *bpy_proxy= PyModule_Create(&bpy_proxy_def);
 	
+	/* Problem:
+	 * 1) this init function is expected to have a private member defined - 'md_def'
+	 *    but this is only set for C defined modules (not py packages)
+	 *    so we cant return 'bpy_package_py' as is.
+	 *
+	 * 2) there is a 'bpy' C module for python to load which is basically all of blender,
+	 *    and there is scripts/bpy/__init__.py, 
+	 *    we may end up having to rename this module so there is no naming conflict here eg:
+	 *    'from blender import bpy'
+	 *
+	 * 3) we dont know the filename at this point, workaround by assigning a dummy value
+	 *    which calls back when its freed so the real loading can take place.
+	 */
+
+	/* assign an object which is freed after __file__ is assigned */
+	dealloc_obj *dob;
 	
+	/* assign dummy type */
+	dealloc_obj_Type.tp_name = "dealloc_obj";
+	dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj);
+	dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc;
+	dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+	
+	if(PyType_Ready(&dealloc_obj_Type) < 0)
+		return NULL;
+
+	dob= (dealloc_obj *) dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0);
+	dob->mod= bpy_proxy; /* borrow */
+	PyModule_AddObject(bpy_proxy, "__file__", (PyObject *)dob); /* borrow */
+
+	return bpy_proxy;
 }
+
 #endif




More information about the Bf-blender-cvs mailing list