Merged changes in the trunk up to revision 35203.

Conflicts resolved:
source/creator/creator.c
source/blender/python/intern/bpy.c
This commit is contained in:
2011-02-26 20:21:09 +00:00
2086 changed files with 13208 additions and 6121 deletions

View File

@@ -27,6 +27,12 @@
* ***** END GPL LICENSE BLOCK *****
*/
/** \file BPY_extern.h
* \ingroup python
*/
#ifndef BPY_EXTERN_H
#define BPY_EXTERN_H
@@ -72,7 +78,7 @@ void BPY_python_end( void );
/* 2.5 UI Scripts */
int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports);
int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports);
int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const short do_jump);
void BPY_text_free_code(struct Text *text);
void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date
void BPY_modules_load_user(struct bContext *C);

View File

@@ -23,6 +23,7 @@ set(INC
../../blenlib
../../makesdna
../../blenkernel
../../blenloader
../../../../intern/guardedalloc
../../../../extern/glew/include
${PYTHON_INCLUDE_DIRS}

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -115,6 +115,7 @@ PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop )
Py_RETURN_NONE;
}
#if 0 /* UNUSED, currenly assignment overwrites into new properties, rather then setting in-place */
static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject *value)
{
switch (prop->type) {
@@ -183,6 +184,7 @@ static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject
}
return 0;
}
#endif
static PyObject *BPy_IDGroup_GetName(BPy_IDProperty *self, void *UNUSED(closure))
{

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -325,13 +325,27 @@ PyObject *BaseMathObject_getWrapped(BaseMathObject *self, void *UNUSED(closure))
return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0);
}
void BaseMathObject_dealloc(BaseMathObject * self)
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
{
Py_VISIT(self->cb_user);
return 0;
}
int BaseMathObject_clear(BaseMathObject *self)
{
Py_CLEAR(self->cb_user);
return 0;
}
void BaseMathObject_dealloc(BaseMathObject *self)
{
/* only free non wrapped */
if(self->wrapped != Py_WRAP)
if(self->wrapped != Py_WRAP) {
PyMem_Free(self->data);
}
BaseMathObject_clear(self);
Py_XDECREF(self->cb_user);
Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes
}

View File

@@ -57,6 +57,9 @@ typedef struct {
PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * );
PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * );
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg);
int BaseMathObject_clear(BaseMathObject *self);
void BaseMathObject_dealloc(BaseMathObject * self);
PyMODINIT_FUNC BPyInit_mathutils(void);

View File

@@ -475,10 +475,10 @@ PyTypeObject color_Type = {
NULL, //tp_getattro
NULL, //tp_setattro
NULL, //tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags
color_doc, //tp_doc
NULL, //tp_traverse
NULL, //tp_clear
(traverseproc)BaseMathObject_traverse, //tp_traverse
(inquiry)BaseMathObject_clear, //tp_clear
(richcmpfunc)Color_richcmpr, //tp_richcompare
0, //tp_weaklistoffset
NULL, //tp_iter
@@ -513,28 +513,31 @@ PyObject *newColorObject(float *col, int type, PyTypeObject *base_type)
{
ColorObject *self;
if(base_type) self = (ColorObject *)base_type->tp_alloc(base_type, 0);
else self = PyObject_NEW(ColorObject, &color_Type);
self= base_type ? (ColorObject *)base_type->tp_alloc(base_type, 0) :
(ColorObject *)PyObject_GC_New(ColorObject, &color_Type);
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(self) {
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(type == Py_WRAP){
self->col = col;
self->wrapped = Py_WRAP;
}
else if (type == Py_NEW){
self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float));
if(col)
copy_v3_v3(self->col, col);
else
zero_v3(self->col);
if(type == Py_WRAP){
self->col = col;
self->wrapped = Py_WRAP;
}
else if (type == Py_NEW){
self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float));
if(col)
copy_v3_v3(self->col, col);
else
zero_v3(self->col);
self->wrapped = Py_NEW;
}
else {
return NULL;
self->wrapped = Py_NEW;
}
else {
PyErr_SetString(PyExc_RuntimeError, "Color(): invalid type");
return NULL;
}
}
return (PyObject *)self;

View File

@@ -608,10 +608,10 @@ PyTypeObject euler_Type = {
NULL, //tp_getattro
NULL, //tp_setattro
NULL, //tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags
euler_doc, //tp_doc
NULL, //tp_traverse
NULL, //tp_clear
(traverseproc)BaseMathObject_traverse, //tp_traverse
(inquiry)BaseMathObject_clear, //tp_clear
(richcmpfunc)Euler_richcmpr, //tp_richcompare
0, //tp_weaklistoffset
NULL, //tp_iter
@@ -646,31 +646,37 @@ PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_t
{
EulerObject *self;
if(base_type) self = (EulerObject *)base_type->tp_alloc(base_type, 0);
else self = PyObject_NEW(EulerObject, &euler_Type);
self= base_type ? (EulerObject *)base_type->tp_alloc(base_type, 0) :
(EulerObject *)PyObject_GC_New(EulerObject, &euler_Type);
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(self) {
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(type == Py_WRAP) {
self->eul = eul;
self->wrapped = Py_WRAP;
}
else if (type == Py_NEW){
self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float));
if(eul)
copy_v3_v3(self->eul, eul);
else
zero_v3(self->eul);
if(type == Py_WRAP) {
self->eul = eul;
self->wrapped = Py_WRAP;
}
else if (type == Py_NEW) {
self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float));
if(eul) {
copy_v3_v3(self->eul, eul);
}
else {
zero_v3(self->eul);
}
self->wrapped = Py_NEW;
}
else{
return NULL;
self->wrapped = Py_NEW;
}
else {
PyErr_SetString(PyExc_RuntimeError, "Euler(): invalid type");
return NULL;
}
self->order= order;
}
self->order= order;
return (PyObject *)self;
}

View File

@@ -1775,10 +1775,10 @@ PyTypeObject matrix_Type = {
NULL, /*tp_getattro*/
NULL, /*tp_setattro*/
NULL, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
matrix_doc, /*tp_doc*/
NULL, /*tp_traverse*/
NULL, /*tp_clear*/
(traverseproc)BaseMathObject_traverse, //tp_traverse
(inquiry)BaseMathObject_clear, //tp_clear
(richcmpfunc)Matrix_richcmpr, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
NULL, /*tp_iter*/
@@ -1826,52 +1826,58 @@ PyObject *newMatrixObject(float *mat, const unsigned short rowSize, const unsign
int x, row, col;
/*matrix objects can be any 2-4row x 2-4col matrix*/
if(rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4){
if(rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4) {
PyErr_SetString(PyExc_RuntimeError, "matrix(): row and column sizes must be between 2 and 4");
return NULL;
}
if(base_type) self = (MatrixObject *)base_type->tp_alloc(base_type, 0);
else self = PyObject_NEW(MatrixObject, &matrix_Type);
self= base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) :
(MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type);
self->row_size = rowSize;
self->col_size = colSize;
if(self) {
self->row_size = rowSize;
self->col_size = colSize;
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(type == Py_WRAP){
self->contigPtr = mat;
/*pointer array points to contigous memory*/
for(x = 0; x < rowSize; x++) {
self->matrix[x] = self->contigPtr + (x * colSize);
if(type == Py_WRAP){
self->contigPtr = mat;
/*pointer array points to contigous memory*/
for(x = 0; x < rowSize; x++) {
self->matrix[x] = self->contigPtr + (x * colSize);
}
self->wrapped = Py_WRAP;
}
self->wrapped = Py_WRAP;
}else if (type == Py_NEW){
self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float));
if(self->contigPtr == NULL) { /*allocation failure*/
PyErr_SetString(PyExc_MemoryError, "matrix(): problem allocating pointer space");
return NULL;
}
/*pointer array points to contigous memory*/
for(x = 0; x < rowSize; x++) {
self->matrix[x] = self->contigPtr + (x * colSize);
}
/*parse*/
if(mat) { /*if a float array passed*/
for(row = 0; row < rowSize; row++) {
for(col = 0; col < colSize; col++) {
self->matrix[row][col] = mat[(row * colSize) + col];
else if (type == Py_NEW){
self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float));
if(self->contigPtr == NULL) { /*allocation failure*/
PyErr_SetString(PyExc_MemoryError, "matrix(): problem allocating pointer space");
return NULL;
}
/*pointer array points to contigous memory*/
for(x = 0; x < rowSize; x++) {
self->matrix[x] = self->contigPtr + (x * colSize);
}
/*parse*/
if(mat) { /*if a float array passed*/
for(row = 0; row < rowSize; row++) {
for(col = 0; col < colSize; col++) {
self->matrix[row][col] = mat[(row * colSize) + col];
}
}
}
} else if (rowSize == colSize ) { /*or if no arguments are passed return identity matrix for square matrices */
PyObject *ret_dummy= Matrix_identity(self);
Py_DECREF(ret_dummy);
else if (rowSize == colSize ) { /*or if no arguments are passed return identity matrix for square matrices */
PyObject *ret_dummy= Matrix_identity(self);
Py_DECREF(ret_dummy);
}
self->wrapped = Py_NEW;
}
else {
PyErr_SetString(PyExc_RuntimeError, "Matrix(): invalid type");
return NULL;
}
self->wrapped = Py_NEW;
}else{ /*bad type*/
return NULL;
}
return (PyObject *) self;
}

View File

@@ -1044,10 +1044,10 @@ PyTypeObject quaternion_Type = {
NULL, //tp_getattro
NULL, //tp_setattro
NULL, //tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags
quaternion_doc, //tp_doc
NULL, //tp_traverse
NULL, //tp_clear
(traverseproc)BaseMathObject_traverse, //tp_traverse
(inquiry)BaseMathObject_clear, //tp_clear
(richcmpfunc)Quaternion_richcmpr, //tp_richcompare
0, //tp_weaklistoffset
NULL, //tp_iter
@@ -1082,26 +1082,31 @@ PyObject *newQuaternionObject(float *quat, int type, PyTypeObject *base_type)
{
QuaternionObject *self;
if(base_type) self = (QuaternionObject *)base_type->tp_alloc(base_type, 0);
else self = PyObject_NEW(QuaternionObject, &quaternion_Type);
self= base_type ? (QuaternionObject *)base_type->tp_alloc(base_type, 0) :
(QuaternionObject *)PyObject_GC_New(QuaternionObject, &quaternion_Type);
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(self) {
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(type == Py_WRAP){
self->quat = quat;
self->wrapped = Py_WRAP;
}else if (type == Py_NEW){
self->quat = PyMem_Malloc(QUAT_SIZE * sizeof(float));
if(!quat) { //new empty
unit_qt(self->quat);
}else{
QUATCOPY(self->quat, quat);
if(type == Py_WRAP){
self->quat = quat;
self->wrapped = Py_WRAP;
}
else if (type == Py_NEW){
self->quat = PyMem_Malloc(QUAT_SIZE * sizeof(float));
if(!quat) { //new empty
unit_qt(self->quat);
}else{
QUATCOPY(self->quat, quat);
}
self->wrapped = Py_NEW;
}
else{
PyErr_SetString(PyExc_RuntimeError, "Quaternion(): invalid type");
return NULL;
}
self->wrapped = Py_NEW;
}else{ //bad type
return NULL;
}
return (PyObject *) self;
}

View File

@@ -2162,14 +2162,15 @@ PyTypeObject vector_Type = {
NULL, /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
vector_doc, /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL, /* traverseproc tp_traverse; */
(traverseproc)BaseMathObject_traverse, //tp_traverse
/* delete references to contained objects */
NULL, /* inquiry tp_clear; */
(inquiry)BaseMathObject_clear, //tp_clear
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
@@ -2218,35 +2219,42 @@ PyObject *newVectorObject(float *vec, const int size, const int type, PyTypeObje
{
VectorObject *self;
if(size > 4 || size < 2)
if(size > 4 || size < 2) {
PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
return NULL;
}
if(base_type) self = (VectorObject *)base_type->tp_alloc(base_type, 0);
else self = PyObject_NEW(VectorObject, &vector_Type);
self= base_type ? (VectorObject *)base_type->tp_alloc(base_type, 0) :
(VectorObject *)PyObject_GC_New(VectorObject, &vector_Type);
self->size = size;
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(self) {
self->size = size;
if(type == Py_WRAP) {
self->vec = vec;
self->wrapped = Py_WRAP;
} else if (type == Py_NEW) {
self->vec= PyMem_Malloc(size * sizeof(float));
if(vec) {
memcpy(self->vec, vec, size * sizeof(float));
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if(type == Py_WRAP) {
self->vec = vec;
self->wrapped = Py_WRAP;
}
else { /* new empty */
fill_vn(self->vec, size, 0.0f);
if(size == 4) { /* do the homogenous thing */
self->vec[3] = 1.0f;
else if (type == Py_NEW) {
self->vec= PyMem_Malloc(size * sizeof(float));
if(vec) {
memcpy(self->vec, vec, size * sizeof(float));
}
else { /* new empty */
fill_vn(self->vec, size, 0.0f);
if(size == 4) { /* do the homogenous thing */
self->vec[3] = 1.0f;
}
}
self->wrapped = Py_NEW;
}
else {
PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid type");
return NULL;
}
self->wrapped = Py_NEW;
}else{ /*bad type*/
return NULL;
}
return (PyObject *) self;
}

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* Blender.Noise BPython module implementation.

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -21,6 +21,7 @@
*/
#include <Python.h>
#include <frameobject.h>
#include "py_capi_utils.h"
@@ -54,39 +55,34 @@ void PyC_LineSpit(void) {
fprintf(stderr, "%s:%d\n", filename, lineno);
}
/* python 3.2 only, copied from frameobjec.c */
#if PY_VERSION_HEX < 0x03020000
int
PyFrame_GetLineNumber(PyFrameObject *f)
{
if (f->f_trace)
return f->f_lineno;
else
return PyCode_Addr2Line(f->f_code, f->f_lasti);
}
#endif
void PyC_FileAndNum(const char **filename, int *lineno)
{
PyObject *getframe, *frame;
PyObject *f_lineno= NULL, *co_filename= NULL;
PyFrameObject *frame;
if (filename) *filename= NULL;
if (lineno) *lineno = -1;
getframe = PySys_GetObject("_getframe"); // borrowed
if (getframe==NULL) {
PyErr_Clear();
if (!(frame= PyThreadState_GET()->frame)) {
return;
}
frame = PyObject_CallObject(getframe, NULL);
if (frame==NULL) {
PyErr_Clear();
return;
}
/* when executing a script */
if (filename) {
co_filename= PyC_Object_GetAttrStringArgs(frame, 2, "f_code", "co_filename");
if (co_filename==NULL) {
PyErr_SetString(PyExc_RuntimeError, "Could not access sys._getframe().f_code.co_filename");
Py_DECREF(frame);
return;
}
*filename = _PyUnicode_AsString(co_filename);
Py_DECREF(co_filename);
*filename = _PyUnicode_AsString(frame->f_code->co_filename);
}
/* when executing a module */
if(filename && *filename == NULL) {
/* try an alternative method to get the filename - module based
@@ -104,21 +100,10 @@ void PyC_FileAndNum(const char **filename, int *lineno)
}
}
}
if (lineno) {
f_lineno= PyObject_GetAttrString(frame, "f_lineno");
if (f_lineno==NULL) {
PyErr_SetString(PyExc_RuntimeError, "Could not access sys._getframe().f_lineno");
Py_DECREF(frame);
return;
}
*lineno = (int)PyLong_AsSsize_t(f_lineno);
Py_DECREF(f_lineno);
}
Py_DECREF(frame);
if (lineno) {
*lineno = PyFrame_GetLineNumber(frame);
}
}
/* Would be nice if python had this built in */

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -29,6 +29,7 @@ set(INC
../../makesdna
../../makesrna
../../blenkernel
../../blenloader
../../windowmanager
../../editors/include
../../freestyle/intern/python
@@ -48,6 +49,7 @@ set(SRC
bpy_rna.c
bpy_rna_array.c
bpy_rna_callback.c
bpy_traceback.c
bpy_util.c
stubs.c
@@ -59,6 +61,7 @@ set(SRC
bpy_props.h
bpy_rna.h
bpy_rna_callback.h
bpy_traceback.h
bpy_util.h
../BPY_extern.h
)
@@ -68,4 +71,8 @@ if(WITH_BUILDINFO)
add_definitions(-DBUILD_DATE)
endif()
if(WITH_PYTHON_MODULE)
add_definitions(-DWITH_PYTHON_MODULE)
endif()
blender_add_lib(bf_python "${SRC}" "${INC}")

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -55,6 +55,8 @@
#include "BPy_Freestyle.h"
PyObject *bpy_package_py= NULL;
static char bpy_script_paths_doc[] =
".. function:: script_paths()\n"
"\n"
@@ -163,7 +165,7 @@ static PyMethodDef meth_bpy_script_paths = {"script_paths", (PyCFunction)bpy_scr
static PyMethodDef meth_bpy_blend_paths = {"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc};
static PyMethodDef meth_bpy_user_resource = {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, NULL};
static void bpy_import_test(const char *modname)
static PyObject *bpy_import_test(const char *modname)
{
PyObject *mod= PyImport_ImportModuleLevel((char *)modname, NULL, NULL, NULL, 0);
if(mod) {
@@ -173,6 +175,8 @@ static void bpy_import_test(const char *modname)
PyErr_Print();
PyErr_Clear();
}
return mod;
}
/*****************************************************************************
@@ -238,5 +242,5 @@ void BPy_init_modules( void )
PyModule_AddObject(mod, meth_bpy_unregister_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_unregister_class, NULL));
/* add our own modules dir, this is a python package */
bpy_import_test("bpy");
bpy_package_py= bpy_import_test("bpy");
}

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -22,4 +22,4 @@
* ***** END GPL LICENSE BLOCK ***** */
void BPy_init_modules( void );
extern PyObject *bpy_package_py;

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -35,6 +35,7 @@
#include "bpy.h"
#include "bpy_rna.h"
#include "bpy_util.h"
#include "bpy_traceback.h"
#include "DNA_space_types.h"
#include "DNA_text_types.h"
@@ -157,6 +158,7 @@ void BPY_modules_update(bContext *C)
}
/* must be called before Py_Initialize */
#ifndef WITH_PYTHON_MODULE
static void bpy_python_start_path(void)
{
char *py_path_bundle= BLI_get_folder(BLENDER_PYTHON, NULL);
@@ -195,8 +197,7 @@ static void bpy_python_start_path(void)
// printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
}
}
#endif
void BPY_context_set(bContext *C)
{
@@ -219,8 +220,9 @@ static struct _inittab bpy_internal_modules[]= {
/* call BPY_context_set first */
void BPY_python_start(int argc, const char **argv)
{
#ifndef WITH_PYTHON_MODULE
PyThreadState *py_tstate = NULL;
/* not essential but nice to set our name */
static wchar_t bprogname_wchar[FILE_MAXDIR+FILE_MAXFILE]; /* python holds a reference */
utf8towchar(bprogname_wchar, bprogname);
@@ -252,8 +254,13 @@ void BPY_python_start(int argc, const char **argv)
/* Initialize thread support (also acquires lock) */
PyEval_InitThreads();
#else
(void)argc;
(void)argv;
PyImport_ExtendInittab(bpy_internal_modules);
#endif
/* bpy.* and lets us import it */
BPy_init_modules();
@@ -281,8 +288,10 @@ void BPY_python_start(int argc, const char **argv)
pyrna_alloc_types();
#ifndef WITH_PYTHON_MODULE
py_tstate = PyGILState_GetThisThreadState();
PyEval_ReleaseThread(py_tstate);
#endif
}
void BPY_python_end(void)
@@ -319,6 +328,18 @@ void BPY_python_end(void)
}
static void python_script_error_jump_text(struct Text *text)
{
int lineno;
int offset;
python_script_error_jump(text->id.name+2, &lineno, &offset);
if(lineno != -1) {
/* select the line with the error */
txt_move_to(text, lineno - 1, INT_MAX, FALSE);
txt_move_to(text, lineno - 1, offset, TRUE);
}
}
/* super annoying, undo _PyModule_Clear(), bug [#23871] */
#define PYMODULE_CLEAR_WORKAROUND
@@ -332,7 +353,7 @@ typedef struct {
} PyModuleObject;
#endif
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const short do_jump)
{
PyObject *main_mod= NULL;
PyObject *py_dict= NULL, *py_result= NULL;
@@ -361,6 +382,9 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
MEM_freeN( buf );
if(PyErr_Occurred()) {
if(do_jump) {
python_script_error_jump_text(text);
}
BPY_text_free_code(text);
}
}
@@ -406,6 +430,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
}
if (!py_result) {
if(text) {
if(do_jump) {
python_script_error_jump_text(text);
}
}
BPy_errors_to_report(reports);
} else {
Py_DECREF( py_result );
@@ -434,13 +463,13 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
/* Can run a file or text block */
int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports)
{
return python_script_exec(C, filepath, NULL, reports);
return python_script_exec(C, filepath, NULL, reports, FALSE);
}
int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports)
int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump)
{
return python_script_exec(C, NULL, text, reports);
return python_script_exec(C, NULL, text, reports, do_jump);
}
void BPY_DECREF(void *pyob_ptr)
@@ -659,3 +688,102 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
return done;
}
#ifdef WITH_PYTHON_MODULE
#include "BLI_storage.h"
/* TODO, reloading the module isnt functional at the moment. */
extern int main_python(int argc, const char **argv);
static struct PyModuleDef bpy_proxy_def = {
PyModuleDef_HEAD_INIT,
"bpy", /* m_name */
NULL, /* m_doc */
0, /* m_size */
NULL, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
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)
{
const int argc= 1;
const char *argv[2];
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() */
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

View File

@@ -1,5 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,5 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -24,6 +24,7 @@
#include <Python.h>
#include <stddef.h>
#include <float.h> /* FLT_MIN/MAX */
#include "bpy_rna.h"
@@ -655,7 +656,7 @@ static long pyrna_prop_hash(BPy_PropertyRNA *self)
}
/* use our own dealloc so we can free a property if we use one */
static void pyrna_struct_dealloc( BPy_StructRNA *self )
static void pyrna_struct_dealloc(BPy_StructRNA *self)
{
if (self->freeptr && self->ptr.data) {
IDP_FreeProperty(self->ptr.data);
@@ -663,9 +664,37 @@ static void pyrna_struct_dealloc( BPy_StructRNA *self )
self->ptr.data= NULL;
}
#ifdef USE_WEAKREFS
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
Py_TYPE(self)->tp_free(self);
}
/* use our own dealloc so we can free a property if we use one */
static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
{
#ifdef USE_WEAKREFS
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
Py_TYPE(self)->tp_free(self);
}
static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
{
#ifdef USE_WEAKREFS
if (self->in_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
}
#endif
/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
Py_TYPE(self)->tp_free(self);
return;
}
static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
@@ -1013,26 +1042,12 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
if (RNA_property_array_check(ptr, prop)) {
/* char error_str[512]; */
int ok= 1;
#ifdef USE_MATHUTILS
if(MatrixObject_Check(value)) {
MatrixObject *mat = (MatrixObject*)value;
if(!BaseMath_ReadCallback(mat))
return -1;
} else /* continue... */
#endif // USE_MATHUTILS
if (!PySequence_Check(value)) {
PyErr_Format(PyExc_TypeError, "%.200s RNA array assignment to %.200s.%.200s expected a sequence, not %.200s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
return -1;
}
/* done getting the length */
ok= pyrna_py_to_array(ptr, prop, data, value, error_prefix);
if (!ok) {
/* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */
return -1;
}
}
@@ -2246,8 +2261,8 @@ static char pyrna_struct_keyframe_insert_doc[] =
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str\n"
" :return: Success of keyframe insertion.\n"
" :rtype: boolean";
" :rtype: boolean\n"
;
static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
{
/* args, pyrna_struct_keyframe_parse handles these */
@@ -2289,8 +2304,8 @@ static char pyrna_struct_keyframe_delete_doc[] =
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
" :type group: str\n"
" :return: Success of keyframe deleation.\n"
" :rtype: boolean";
" :rtype: boolean\n"
;
static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
{
/* args, pyrna_struct_keyframe_parse handles these */
@@ -2329,8 +2344,8 @@ static char pyrna_struct_driver_add_doc[] =
" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :return: The driver(s) added.\n"
" :rtype: :class:`FCurve` or list if index is -1 with an array property.";
" :rtype: :class:`FCurve` or list if index is -1 with an array property.\n"
;
static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
{
const char *path, *path_full;
@@ -2401,8 +2416,8 @@ static char pyrna_struct_driver_remove_doc[] =
" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
" :type index: int\n"
" :return: Success of driver removal.\n"
" :rtype: boolean";
" :rtype: boolean\n"
;
static PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
{
const char *path, *path_full;
@@ -2438,8 +2453,8 @@ static char pyrna_struct_is_property_set_doc[] =
" Check if a property is set, use for testing operator properties.\n"
"\n"
" :return: True when the property has been set.\n"
" :rtype: boolean";
" :rtype: boolean\n"
;
static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
{
PropertyRNA *prop;
@@ -2478,8 +2493,8 @@ static char pyrna_struct_is_property_hidden_doc[] =
" Check if a property is hidden.\n"
"\n"
" :return: True when the property is hidden.\n"
" :rtype: boolean";
" :rtype: boolean\n"
;
static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
{
PropertyRNA *prop;
@@ -2504,8 +2519,8 @@ static char pyrna_struct_path_resolve_doc[] =
" :arg path: path which this property resolves.\n"
" :type path: string\n"
" :arg coerce: optional argument, when True, the property will be converted into its python representation.\n"
" :type coerce: boolean\n";
" :type coerce: boolean\n"
;
static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
{
const char *path;
@@ -2555,8 +2570,8 @@ static char pyrna_struct_path_from_id_doc[] =
" :arg property: Optional property name which can be used if the path is to a property of this object.\n"
" :type property: string\n"
" :return: The path from :class:`bpy_struct.id_data` to this struct and property (when given).\n"
" :rtype: str";
" :rtype: str\n"
;
static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
{
const char *name= NULL;
@@ -2598,8 +2613,8 @@ static char pyrna_prop_path_from_id_doc[] =
" 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";
" :rtype: str\n"
;
static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
{
const char *path;
@@ -2625,8 +2640,8 @@ static char pyrna_struct_type_recast_doc[] =
" 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`";
" :rtype: subclass of :class:`bpy_struct`\n"
;
static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
{
PointerRNA r_ptr;
@@ -3244,10 +3259,10 @@ static char pyrna_struct_get_doc[] =
" :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"
" :type default: Undefined\n"
"\n"
" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\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)
{
IDProperty *group, *idprop;
@@ -3283,8 +3298,8 @@ static char pyrna_struct_as_pointer_doc[] =
" :return: int (memory address).\n"
" :rtype: int\n"
"\n"
" .. note:: This is intended only for advanced script writers who need to pass blender data to their own C/Python modules.\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)
{
return PyLong_FromVoidPtr(self->ptr.data);
@@ -3937,6 +3952,16 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
/* for testing */
/*
{
const char *fn;
int lineno;
PyC_FileAndNum(&fn, &lineno);
printf("pyrna_func_call > %.200s.%.200s : %.200s:%d\n", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), fn, lineno);
}
*/
/* include the ID pointer for pyrna_param_to_py() so we can include the
* ID pointer on return values, this only works when returned values have
* the same ID as the functions. */
@@ -4228,10 +4253,10 @@ PyTypeObject pyrna_struct_meta_idprop_Type = {
PyTypeObject pyrna_struct_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_struct", /* tp_name */
sizeof( BPy_StructRNA ), /* tp_basicsize */
sizeof(BPy_StructRNA), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
( destructor ) pyrna_struct_dealloc,/* tp_dealloc */
(destructor) pyrna_struct_dealloc,/* tp_dealloc */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
@@ -4271,8 +4296,11 @@ PyTypeObject pyrna_struct_Type = {
(richcmpfunc)pyrna_struct_richcmp, /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0, /* long tp_weaklistoffset; */
#ifdef USE_WEAKREFS
offsetof(BPy_StructRNA, in_weakreflist), /* long tp_weaklistoffset; */
#else
0,
#endif
/*** Added in release 2.2 ***/
/* Iterators */
NULL, /* getiterfunc tp_iter; */
@@ -4307,11 +4335,11 @@ PyTypeObject pyrna_struct_Type = {
PyTypeObject pyrna_prop_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
sizeof(BPy_PropertyRNA), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
NULL, /* tp_dealloc */
NULL, /* printfunc tp_print; */
(destructor) pyrna_prop_dealloc, /* tp_dealloc */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
@@ -4352,7 +4380,11 @@ PyTypeObject pyrna_prop_Type = {
(richcmpfunc)pyrna_prop_richcmp, /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0, /* long tp_weaklistoffset; */
#ifdef USE_WEAKREFS
offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
#else
0,
#endif
/*** Added in release 2.2 ***/
/* Iterators */
@@ -4387,10 +4419,10 @@ PyTypeObject pyrna_prop_Type = {
PyTypeObject pyrna_prop_array_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop_array", /* tp_name */
sizeof( BPy_PropertyArrayRNA ), /* tp_basicsize */
0, /* tp_itemsize */
sizeof(BPy_PropertyArrayRNA), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
NULL, /* tp_dealloc */
(destructor)pyrna_prop_array_dealloc, /* tp_dealloc */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
@@ -4432,8 +4464,11 @@ PyTypeObject pyrna_prop_array_Type = {
NULL, /* subclassed */ /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0, /* long tp_weaklistoffset; */
#ifdef USE_WEAKREFS
offsetof(BPy_PropertyArrayRNA, in_weakreflist), /* long tp_weaklistoffset; */
#else
0,
#endif
/*** Added in release 2.2 ***/
/* Iterators */
(getiterfunc)pyrna_prop_array_iter, /* getiterfunc tp_iter; */
@@ -4467,10 +4502,10 @@ PyTypeObject pyrna_prop_array_Type = {
PyTypeObject pyrna_prop_collection_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop_collection", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
sizeof(BPy_PropertyRNA), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
NULL, /* tp_dealloc */
(destructor)pyrna_prop_dealloc, /* tp_dealloc */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
@@ -4512,7 +4547,11 @@ PyTypeObject pyrna_prop_collection_Type = {
NULL, /* subclassed */ /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0, /* long tp_weaklistoffset; */
#ifdef USE_WEAKREFS
offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
#else
0,
#endif
/*** Added in release 2.2 ***/
/* Iterators */
@@ -4548,10 +4587,10 @@ PyTypeObject pyrna_prop_collection_Type = {
static PyTypeObject pyrna_prop_collection_idprop_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop_collection_idprop", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
0, /* tp_itemsize */
sizeof(BPy_PropertyRNA), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
NULL, /* tp_dealloc */
(destructor)pyrna_prop_dealloc, /* tp_dealloc */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
@@ -4593,7 +4632,11 @@ static PyTypeObject pyrna_prop_collection_idprop_Type = {
NULL, /* subclassed */ /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0, /* long tp_weaklistoffset; */
#ifdef USE_WEAKREFS
offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
#else
0,
#endif
/*** Added in release 2.2 ***/
/* Iterators */
@@ -4834,6 +4877,9 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
else {
fprintf(stderr, "Could not make type\n");
pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
#ifdef USE_WEAKREFS
pyrna->in_weakreflist= NULL;
#endif
}
}
@@ -4870,11 +4916,17 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
}
pyrna = (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyRNA, type);
#ifdef USE_WEAKREFS
pyrna->in_weakreflist= NULL;
#endif
}
else {
pyrna = (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyArrayRNA, &pyrna_prop_array_Type);
((BPy_PropertyArrayRNA *)pyrna)->arraydim= 0;
((BPy_PropertyArrayRNA *)pyrna)->arrayoffset= 0;
#ifdef USE_WEAKREFS
((BPy_PropertyArrayRNA *)pyrna)->in_weakreflist= NULL;
#endif
}
if( !pyrna ) {
@@ -5019,7 +5071,7 @@ PyObject *BPY_rna_types(void)
if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY)==0) {
pyrna_basetype_Type.tp_name = "RNA_Types";
pyrna_basetype_Type.tp_basicsize = sizeof( BPy_BaseTypeRNA );
pyrna_basetype_Type.tp_basicsize = sizeof(BPy_BaseTypeRNA);
pyrna_basetype_Type.tp_getattro = ( getattrofunc )pyrna_basetype_getattro;
pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT;
pyrna_basetype_Type.tp_methods = pyrna_basetype_methods;
@@ -5033,7 +5085,9 @@ PyObject *BPY_rna_types(void)
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create(&self->ptr);
self->prop = RNA_struct_find_property(&self->ptr, "structs");
#ifdef USE_WEAKREFS
self->in_weakreflist= NULL;
#endif
return (PyObject *)self;
}
@@ -5415,7 +5469,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
/* testing, for correctness, not operator and not draw function */
const short is_readonly= strstr("draw", func_id) || /*strstr("render", func_id) ||*/ !RNA_struct_is_a(ptr->type, &RNA_Operator);
#endif
py_class= RNA_struct_py_type_get(ptr->type);
/* rare case. can happen when registering subclasses */

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -39,21 +39,33 @@ extern PyTypeObject pyrna_prop_collection_Type;
#define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type))
#define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type)
/* play it safe and keep optional for now, need to test further now this affects looping on 10000's of verts for eg. */
// #define USE_WEAKREFS
typedef struct {
PyObject_HEAD /* required python macro */
PointerRNA ptr;
PointerRNA ptr;
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
} BPy_DummyPointerRNA;
typedef struct {
PyObject_HEAD /* required python macro */
PointerRNA ptr;
int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
} BPy_StructRNA;
typedef struct {
PyObject_HEAD /* required python macro */
PointerRNA ptr;
PropertyRNA *prop;
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
} BPy_PropertyRNA;
typedef struct {
@@ -64,6 +76,9 @@ typedef struct {
/* Arystan: this is a hack to allow sub-item r/w access like: face.uv[n][m] */
int arraydim; /* array dimension, e.g: 0 for face.uv, 2 for face.uv[n][m], etc. */
int arrayoffset; /* array first item offset, e.g. if face.uv is [4][2], arrayoffset for face.uv[n] is 2n */
#ifdef USE_WEAKREFS
PyObject *in_weakreflist;
#endif
} BPy_PropertyArrayRNA;
/* cheap trick */

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -98,7 +98,7 @@ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[]
Py_DECREF(item);
/* BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str); */
PyErr_Format(PyExc_TypeError, "expected sequence items of type %s, not %s", item_type_str, Py_TYPE(item)->tp_name);
PyErr_Format(PyExc_TypeError, "%s expected sequence items of type %s, not %s", error_prefix, item_type_str, Py_TYPE(item)->tp_name);
return 0;
}
@@ -110,21 +110,22 @@ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[]
}
/* Returns the number of items in a single- or multi-dimensional sequence. */
static int count_items(PyObject *seq)
static int count_items(PyObject *seq, int dim)
{
int totitem= 0;
if (PySequence_Check(seq)) {
if(dim > 1) {
const int seq_size= PySequence_Size(seq);
int i;
for (i= 0; i < seq_size; i++) {
PyObject *item= PySequence_GetItem(seq, i);
totitem += count_items(item);
totitem += count_items(item, dim - 1);
Py_DECREF(item);
}
}
else
totitem= 1;
else {
totitem= PySequence_Size(seq);
}
return totitem;
}
@@ -135,8 +136,8 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA
int dimsize[MAX_ARRAY_DIMENSION];
int tot, totdim, len;
tot= count_items(rvalue);
totdim= RNA_property_array_dimension(ptr, prop, dimsize);
tot= count_items(rvalue, totdim - lvalue_dim);
if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
if (RNA_property_array_length(ptr, prop) != tot) {
@@ -186,7 +187,7 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA
if (tot != len) {
/* BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); */
PyErr_Format(PyExc_ValueError, "%s sequence must have %d items total, not %d", error_prefix, len, tot);
PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, sequence must have %d items total, not %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), len, tot);
return 0;
}
}
@@ -315,7 +316,7 @@ static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, i
if(lvalue_dim == totdim) { /* single item, assign directly */
if(!check_item_type(py)) {
PyErr_Format(PyExc_TypeError, "%s expected a %s type, not %s", error_prefix, item_type_str, Py_TYPE(py)->tp_name);
PyErr_Format(PyExc_TypeError, "%s %.200s.%.200s, expected a %s type, not %s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), item_type_str, Py_TYPE(py)->tp_name);
return 0;
}
copy_value_single(py, ptr, prop, NULL, 0, &index, convert_item, rna_set_index);

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****

View File

@@ -0,0 +1,151 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <Python.h>
#include <frameobject.h>
#include "bpy_traceback.h"
static const char *traceback_filepath(PyTracebackObject *tb)
{
return _PyUnicode_AsString(tb->tb_frame->f_code->co_filename);
}
/* copied from pythonrun.c, 3.2.0 */
static int
parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
int *lineno, int *offset, const char **text)
{
long hold;
PyObject *v;
/* old style errors */
if (PyTuple_Check(err))
return PyArg_ParseTuple(err, "O(ziiz)", message, filename,
lineno, offset, text);
/* new style errors. `err' is an instance */
if (! (v = PyObject_GetAttrString(err, "msg")))
goto finally;
*message = v;
if (!(v = PyObject_GetAttrString(err, "filename")))
goto finally;
if (v == Py_None)
*filename = NULL;
else if (! (*filename = _PyUnicode_AsString(v)))
goto finally;
Py_DECREF(v);
if (!(v = PyObject_GetAttrString(err, "lineno")))
goto finally;
hold = PyLong_AsLong(v);
Py_DECREF(v);
v = NULL;
if (hold < 0 && PyErr_Occurred())
goto finally;
*lineno = (int)hold;
if (!(v = PyObject_GetAttrString(err, "offset")))
goto finally;
if (v == Py_None) {
*offset = -1;
Py_DECREF(v);
v = NULL;
} else {
hold = PyLong_AsLong(v);
Py_DECREF(v);
v = NULL;
if (hold < 0 && PyErr_Occurred())
goto finally;
*offset = (int)hold;
}
if (!(v = PyObject_GetAttrString(err, "text")))
goto finally;
if (v == Py_None)
*text = NULL;
else if (!PyUnicode_Check(v) ||
!(*text = _PyUnicode_AsString(v)))
goto finally;
Py_DECREF(v);
return 1;
finally:
Py_XDECREF(v);
return 0;
}
/* end copied function! */
void python_script_error_jump(const char *filepath, int *lineno, int *offset)
{
PyObject *exception, *value;
PyTracebackObject *tb;
*lineno= -1;
*offset= 0;
PyErr_Fetch(&exception, &value, (PyObject **)&tb);
if(exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
/* no traceback available when SyntaxError.
* python has no api's to this. reference parse_syntax_error() from pythonrun.c */
PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */
if(value) { /* should always be true */
PyObject *message;
const char *filename, *text;
if(parse_syntax_error(value, &message, &filename, lineno, offset, &text)) {
/* python adds a '/', prefix, so check for both */
if( (strcmp(filename, filepath) == 0) ||
((filename[0] == '\\' || filename[0] == '/') && strcmp(filename + 1, filepath) == 0)
) {
/* good */
}
else {
*lineno= -1;
}
}
else {
*lineno= -1;
}
}
/* this avoids an abort in Python 2.3's garbage collecting */
}
else {
PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */
PyErr_Print();
for(tb= (PyTracebackObject *)PySys_GetObject("last_traceback"); tb && (PyObject *)tb != Py_None; tb= tb->tb_next) {
if(strcmp(traceback_filepath(tb), filepath) != 0) {
*lineno= tb->tb_lineno;
break;
}
}
}
}

View File

@@ -0,0 +1,28 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BPY_TRACEBACK_H
#define BPY_TRACEBACK_H
void python_script_error_jump(const char *filepath, int *lineno, int *offset);
#endif // BPY_TRACEBACK_H

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -36,94 +36,6 @@ static bContext* __py_context = NULL;
bContext* BPy_GetContext(void) { return __py_context; }
void BPy_SetContext(bContext *C) { __py_context= C; }
int BPY_class_validate(const char *class_type, PyObject *class, PyObject *base_class, BPY_class_attr_check* class_attrs, PyObject **py_class_attrs)
{
PyObject *item, *fitem;
PyObject *py_arg_count;
int i, arg_count;
if (base_class) {
if (!PyObject_IsSubclass(class, base_class)) {
PyObject *name= PyObject_GetAttrString(base_class, "__name__");
PyErr_Format(PyExc_AttributeError, "expected %s subclass of class \"%s\"", class_type, name ? _PyUnicode_AsString(name):"<UNKNOWN>");
Py_XDECREF(name);
return -1;
}
}
for(i= 0;class_attrs->name; class_attrs++, i++) {
item = PyObject_GetAttrString(class, class_attrs->name);
if (py_class_attrs)
py_class_attrs[i]= item;
if (item==NULL) {
if ((class_attrs->flag & BPY_CLASS_ATTR_OPTIONAL)==0) {
PyErr_Format(PyExc_AttributeError, "expected %s class to have an \"%s\" attribute", class_type, class_attrs->name);
return -1;
}
PyErr_Clear();
}
else {
Py_DECREF(item); /* no need to keep a ref, the class owns it */
if((item==Py_None) && (class_attrs->flag & BPY_CLASS_ATTR_NONE_OK)) {
/* dont do anything, this is ok, dont bother checking other types */
}
else {
switch(class_attrs->type) {
case 's':
if (PyUnicode_Check(item)==0) {
PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute to be a string", class_type, class_attrs->name);
return -1;
}
if(class_attrs->len != -1 && class_attrs->len < PyUnicode_GetSize(item)) {
PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute string to be shorter then %d", class_type, class_attrs->name, class_attrs->len);
return -1;
}
break;
case 'l':
if (PyList_Check(item)==0) {
PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute to be a list", class_type, class_attrs->name);
return -1;
}
if(class_attrs->len != -1 && class_attrs->len < PyList_GET_SIZE(item)) {
PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute list to be shorter then %d", class_type, class_attrs->name, class_attrs->len);
return -1;
}
break;
case 'f':
if (PyMethod_Check(item))
fitem= PyMethod_Function(item); /* py 2.x */
else
fitem= item; /* py 3.x */
if (PyFunction_Check(fitem)==0) {
PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute to be a function", class_type, class_attrs->name);
return -1;
}
if (class_attrs->arg_count >= 0) { /* -1 if we dont care*/
py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(fitem), "co_argcount");
arg_count = PyLong_AsSsize_t(py_arg_count);
Py_DECREF(py_arg_count);
if (arg_count != class_attrs->arg_count) {
PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" function to have %d args", class_type, class_attrs->name, class_attrs->arg_count);
return -1;
}
}
break;
}
}
}
}
return 0;
}
char *BPy_enum_as_string(EnumPropertyItem *item)
{
DynStr *dynstr= BLI_dynstr_new();

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -34,24 +34,8 @@
struct EnumPropertyItem;
struct ReportList;
/* Class type checking, use for checking classes can be added as operators, panels etc */
typedef struct BPY_class_attr_check {
const char *name; /* name of the class attribute */
char type; /* 's' = string, 'f' = function, 'l' = list, (add as needed) */
int arg_count; /* only for function types, -1 for undefined, includes self arg */
int len; /* only for string types currently */
int flag; /* other options */
} BPY_class_attr_check;
/* BPY_class_attr_check, flag */
#define BPY_CLASS_ATTR_OPTIONAL 1
#define BPY_CLASS_ATTR_NONE_OK 2
int BPY_class_validate(const char *class_type, PyObject *class, PyObject *base_class, BPY_class_attr_check* class_attrs, PyObject **py_class_attrs);
char *BPy_enum_as_string(struct EnumPropertyItem *item);
#define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL}
/* error reporting */

View File

@@ -1,4 +1,4 @@
/**
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****