~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/python/api2_2x/Camera.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2007-05-17 11:47:59 UTC
  • mfrom: (1.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20070517114759-yp4ybrnhp2u7pk66
Tags: 2.44-1
* New upstream release.
* Drop debian/patches/01_64bits_stupidity, not needed anymore: as of this
  version blender is 64 bits safe again. Adjust README.Debian accordingly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* 
2
 
 * $Id: Camera.c,v 1.43 2007/01/22 00:04:13 campbellbarton Exp $
 
2
 * $Id: Camera.c,v 1.58 2007/04/28 18:20:43 campbellbarton Exp $
3
3
 *
4
4
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5
5
 *
37
37
#include "BKE_object.h"
38
38
#include "BKE_library.h"
39
39
#include "BLI_blenlib.h"
 
40
#include "BLI_arithb.h" /* for M_PI */
40
41
#include "BSE_editipo.h"
41
42
#include "BIF_space.h"
42
43
#include "mydevice.h"
43
44
#include "gen_utils.h"
 
45
#include "gen_library.h"
44
46
#include "Ipo.h"
45
47
 
46
48
 
51
53
 
52
54
enum cam_consts {
53
55
        EXPP_CAM_ATTR_LENS = 0,
 
56
        EXPP_CAM_ATTR_ANGLE,
54
57
        EXPP_CAM_ATTR_DOFDIST,
55
58
        EXPP_CAM_ATTR_CLIPEND,
56
59
        EXPP_CAM_ATTR_CLIPSTART,
109
112
/*****************************************************************************/
110
113
/* Python BPy_Camera methods declarations:                                   */
111
114
/*****************************************************************************/
112
 
static PyObject *Camera_oldgetIpo( BPy_Camera * self );
113
 
static PyObject *Camera_oldgetName( BPy_Camera * self );
114
115
static PyObject *Camera_oldgetType( BPy_Camera * self );
115
116
static PyObject *Camera_oldgetMode( BPy_Camera * self );
116
117
static PyObject *Camera_oldgetLens( BPy_Camera * self );
118
119
static PyObject *Camera_oldgetClipEnd( BPy_Camera * self );
119
120
static PyObject *Camera_oldgetDrawSize( BPy_Camera * self );
120
121
static PyObject *Camera_oldgetScale( BPy_Camera * self );
 
122
static PyObject *Camera_getIpo( BPy_Camera * self );
 
123
static int Camera_setIpo( BPy_Camera * self, PyObject * value );
121
124
static PyObject *Camera_oldsetIpo( BPy_Camera * self, PyObject * args );
122
 
static PyObject *Camera_oldsetName( BPy_Camera * self, PyObject * args );
123
125
static PyObject *Camera_oldsetType( BPy_Camera * self, PyObject * args );
124
126
static PyObject *Camera_oldsetMode( BPy_Camera * self, PyObject * args );
125
127
static PyObject *Camera_oldsetLens( BPy_Camera * self, PyObject * args );
134
136
static PyObject *Camera_insertIpoKey( BPy_Camera * self, PyObject * args );
135
137
static PyObject *Camera_copy( BPy_Camera * self );
136
138
 
137
 
Camera *GetCameraByName( char *name );
138
 
 
139
139
 
140
140
/*****************************************************************************/
141
141
/* Python BPy_Camera methods table:                                          */
142
142
/*****************************************************************************/
143
143
static PyMethodDef BPy_Camera_methods[] = {
144
144
        /* name, method, flags, doc */
145
 
        {"getIpo", ( PyCFunction ) Camera_oldgetIpo, METH_NOARGS,
 
145
        {"getIpo", ( PyCFunction ) Camera_getIpo, METH_NOARGS,
146
146
         "() - Return Camera Data Ipo"},
147
 
        {"getName", ( PyCFunction ) Camera_oldgetName, METH_NOARGS,
 
147
        {"getName", ( PyCFunction ) GenericLib_getName, METH_NOARGS,
148
148
         "() - Return Camera Data name"},
149
149
        {"getType", ( PyCFunction ) Camera_oldgetType, METH_NOARGS,
150
150
         "() - Return Camera type - 'persp':0, 'ortho':1"},
167
167
         "() - Unlink Ipo from this Camera."},
168
168
         {"insertIpoKey", ( PyCFunction ) Camera_insertIpoKey, METH_VARARGS,
169
169
         "( Camera IPO type ) - Inserts a key into IPO"},
170
 
        {"setName", ( PyCFunction ) Camera_oldsetName, METH_VARARGS,
 
170
        {"setName", ( PyCFunction ) GenericLib_setName_with_method, METH_VARARGS,
171
171
         "(s) - Set Camera Data name"},
172
172
        {"setType", ( PyCFunction ) Camera_oldsetType, METH_VARARGS,
173
173
         "(s) - Set Camera type, which can be 'persp' or 'ortho'"},
197
197
         "([s1<,s2,s3...>]) - Delete specified scriptlinks from this camera."},
198
198
        {"__copy__", ( PyCFunction ) Camera_copy, METH_NOARGS,
199
199
         "() - Return a copy of the camera."},
 
200
        {"copy", ( PyCFunction ) Camera_copy, METH_NOARGS,
 
201
         "() - Return a copy of the camera."},
200
202
        {NULL, NULL, 0, NULL}
201
203
};
202
204
 
203
205
/*****************************************************************************/
204
206
/* Python Camera_Type callback function prototypes:                          */
205
207
/*****************************************************************************/
206
 
static void Camera_dealloc( BPy_Camera * self );
207
 
//static int Camera_setAttr( BPy_Camera * self, char *name, PyObject * v );
208
208
static int Camera_compare( BPy_Camera * a, BPy_Camera * b );
209
 
//static PyObject *Camera_getAttr( BPy_Camera * self, char *name );
210
209
static PyObject *Camera_repr( BPy_Camera * self );
211
210
 
212
 
 
213
 
//~ /*****************************************************************************/
214
 
//~ /* Python Camera_Type structure definition:                              */
215
 
//~ /*****************************************************************************/
216
 
//~ PyTypeObject Camera_Type = {
217
 
        //~ PyObject_HEAD_INIT( NULL ) /* required macro */ 
218
 
        //~ NULL,       /* ob_size */
219
 
        //~ "Blender Camera",   /* tp_name */
220
 
        //~ sizeof( BPy_Camera ),       /* tp_basicsize */
221
 
        //~ NULL,                       /* tp_itemsize */
222
 
        //~ /* methods */
223
 
        //~ ( destructor ) Camera_dealloc,      /* tp_dealloc */
224
 
        //~ NULL,                       /* tp_print */
225
 
        //~ NULL,       /* tp_getattr */
226
 
        //~ NULL,       /* tp_setattr */
227
 
        //~ ( cmpfunc ) Camera_compare, /* tp_compare */
228
 
        //~ ( reprfunc ) Camera_repr,   /* tp_repr */
229
 
        //~ NULL,                       /* tp_as_number */
230
 
        //~ NULL,                       /* tp_as_sequence */
231
 
        //~ NULL,                       /* tp_as_mapping */
232
 
        //~ NULL,                       /* tp_as_hash */
233
 
        //~ 0, 0, 0, 0, 0, 0,
234
 
        //~ 0,                  /* tp_doc */
235
 
        //~ 0, 0, 0, 0, 0, 0,
236
 
        //~ BPy_Camera_methods, /* tp_methods */
237
 
        //~ 0,                  /* tp_members */
238
 
        //~ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
239
 
//~ };
240
 
 
241
 
 
242
 
 
243
 
 
244
 
 
245
 
 
246
 
 
247
 
 
248
 
 
249
 
 
250
 
 
251
 
 
252
 
 
253
 
 
254
 
 
255
 
 
256
 
 
257
 
 
258
 
 
259
 
 
260
211
static PyObject *M_Camera_New( PyObject * self, PyObject * args,
261
212
                               PyObject * kwords )
262
213
{
263
214
        char *type_str = "persp";       /* "persp" is type 0, "ortho" is type 1 */
264
 
        char *name_str = "CamData";
 
215
        char *name_str = "Camera";
265
216
        static char *kwlist[] = { "type_str", "name_str", NULL };
266
217
        PyObject *pycam;        /* for Camera Data object wrapper in Python */
267
218
        Camera *blcam;          /* for actual Camera Data we create in Blender */
268
 
        char buf[21];
269
219
 
270
220
        /* Parse the arguments passed in by the Python interpreter */
271
221
        if( !PyArg_ParseTupleAndKeywords( args, kwords, "|ss", kwlist,
274
224
                return EXPP_ReturnPyObjError( PyExc_AttributeError,
275
225
                                              "expected zero, one or two strings as arguments" );
276
226
 
277
 
        blcam = add_camera(  ); /* first create the Camera Data in Blender */
 
227
        blcam = add_camera( name_str ); /* first create the Camera Data in Blender */
278
228
 
279
229
        if( blcam )             /* now create the wrapper obj in Python */
280
230
                pycam = Camera_CreatePyObject( blcam );
300
250
        else
301
251
                return EXPP_ReturnPyObjError( PyExc_AttributeError,
302
252
                                              "unknown camera type" );
303
 
 
304
 
        if( strcmp( name_str, "CamData" ) == 0 )
305
 
                return pycam;
306
 
        else {                  /* user gave us a name for the camera, use it */
307
 
                PyOS_snprintf( buf, sizeof( buf ), "%s", name_str );
308
 
                rename_id( &blcam->id, buf );   /* proper way in Blender */
309
 
        }
310
 
 
 
253
        
311
254
        return pycam;
312
255
}
313
256
 
392
335
        return submodule;
393
336
}
394
337
 
395
 
 
396
 
 
397
 
 
398
 
 
399
 
 
400
 
 
401
 
 
402
 
 
403
 
 
404
 
 
405
 
 
406
 
 
407
 
 
408
 
 
409
 
 
410
 
 
411
 
 
412
 
 
413
 
 
414
338
/* Three Python Camera_Type helper functions needed by the Object module: */
415
339
 
416
340
PyObject *Camera_CreatePyObject( Camera * cam )
424
348
                                              "couldn't create BPy_Camera PyObject" );
425
349
 
426
350
        pycam->camera = cam;
427
 
 
428
351
        return ( PyObject * ) pycam;
429
352
}
430
353
 
431
 
int Camera_CheckPyObject( PyObject * pyobj )
432
 
{
433
 
        return ( pyobj->ob_type == &Camera_Type );
434
 
}
435
 
 
436
354
Camera *Camera_FromPyObject( PyObject * pyobj )
437
355
{
438
356
        return ( ( BPy_Camera * ) pyobj )->camera;
439
357
}
440
358
 
441
359
/*****************************************************************************/
442
 
/* Description: Returns the object with the name specified by the argument  */
443
 
/*      name. Note that the calling function has to remove the first */
444
 
/*      two characters of the object name. These two characters          */
445
 
/*      specify the type of the object (OB, ME, WO, ...)                 */
446
 
/*      The function will return NULL when no object with the given  */
447
 
/*      name is found.                                                      */
448
 
/*****************************************************************************/
449
 
Camera *GetCameraByName( char *name )
450
 
{
451
 
        Camera *cam_iter;
452
 
 
453
 
        cam_iter = G.main->camera.first;
454
 
        while( cam_iter ) {
455
 
                if( StringEqual( name, GetIdName( &( cam_iter->id ) ) ) ) {
456
 
                        return ( cam_iter );
457
 
                }
458
 
                cam_iter = cam_iter->id.next;
459
 
        }
460
 
 
461
 
        /* There is no camera with the given name */
462
 
        return ( NULL );
463
 
}
464
 
 
465
 
/*****************************************************************************/
466
360
/* Python BPy_Camera methods:                                               */
467
361
/*****************************************************************************/
468
362
 
469
 
static PyObject *Camera_oldgetIpo( BPy_Camera * self )
470
 
{
471
 
        struct Ipo *ipo = self->camera->ipo;
472
 
 
473
 
        if( !ipo )
474
 
                Py_RETURN_NONE;
475
 
 
476
 
        return Ipo_CreatePyObject( ipo );
477
 
}
478
 
 
479
 
 
480
 
static PyObject *Camera_oldgetName( BPy_Camera * self )
481
 
{
482
 
 
483
 
        PyObject *attr = PyString_FromString( self->camera->id.name + 2 );
484
 
 
485
 
        if( attr )
486
 
                return attr;
487
 
 
488
 
        return EXPP_ReturnPyObjError( PyExc_RuntimeError,
489
 
                                      "couldn't get Camera.name attribute" );
490
 
}
491
 
 
492
363
static PyObject *Camera_oldgetType( BPy_Camera * self )
493
364
{
494
365
        PyObject *attr = PyInt_FromLong( self->camera->type );
570
441
 
571
442
static PyObject *Camera_oldsetIpo( BPy_Camera * self, PyObject * args )
572
443
{
573
 
        PyObject *pyipo = 0;
574
 
        Ipo *ipo = NULL;
575
 
        Ipo *oldipo;
576
 
 
577
 
        if( !PyArg_ParseTuple( args, "O!", &Ipo_Type, &pyipo ) )
578
 
                return EXPP_ReturnPyObjError( PyExc_TypeError,
579
 
                                              "expected Ipo as argument" );
580
 
 
581
 
        ipo = Ipo_FromPyObject( pyipo );
582
 
 
583
 
        if( !ipo )
584
 
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
585
 
                                              "null ipo!" );
586
 
 
587
 
        if( ipo->blocktype != ID_CA )
588
 
                return EXPP_ReturnPyObjError( PyExc_TypeError,
589
 
                                              "this ipo is not a camera data ipo" );
590
 
 
591
 
        oldipo = self->camera->ipo;
592
 
        if( oldipo ) {
593
 
                ID *id = &oldipo->id;
594
 
                if( id->us > 0 )
595
 
                        id->us--;
596
 
        }
597
 
 
598
 
        id_us_plus(&ipo->id);
599
 
 
600
 
        self->camera->ipo = ipo;
601
 
 
602
 
        Py_RETURN_NONE;
 
444
        return EXPP_setterWrapper( (void *)self, args, (setter)Camera_setIpo );
603
445
}
604
446
 
605
447
static PyObject *Camera_oldclearIpo( BPy_Camera * self )
619
461
        return EXPP_incr_ret_False(); /* no ipo found */
620
462
}
621
463
 
622
 
static PyObject *Camera_oldsetName( BPy_Camera * self, PyObject * args )
623
 
{
624
 
        char *name;
625
 
 
626
 
        if( !PyArg_ParseTuple( args, "s", &name ) )
627
 
                return EXPP_ReturnPyObjError( PyExc_TypeError,
628
 
                                              "expected string argument" );
629
 
 
630
 
        rename_id( &self->camera->id, name );
631
 
 
632
 
        Py_RETURN_NONE;
633
 
}
634
 
 
635
464
static PyObject *Camera_oldsetType( BPy_Camera * self, PyObject * args )
636
465
{
637
466
        char *type;
825
654
        return pycam;
826
655
}
827
656
 
828
 
static void Camera_dealloc( BPy_Camera * self )
829
 
{
830
 
        PyObject_DEL( self );
831
 
}
832
 
 
833
 
static PyObject *Camera_getName( BPy_Camera * self )
834
 
{
835
 
        return PyString_FromString( self->camera->id.name + 2 );
836
 
}
837
 
 
838
 
static int Camera_setName( BPy_Camera * self, PyObject * value )
839
 
{
840
 
        char *name = NULL;
841
 
        
842
 
        name = PyString_AsString ( value );
843
 
        if( !name )
844
 
                return EXPP_ReturnIntError( PyExc_TypeError,
845
 
                                              "expected string argument" );
846
 
        
847
 
        rename_id( &self->camera->id, name);
848
 
        return 0;
849
 
}
850
 
 
851
 
 
852
 
static PyObject *Camera_getUsers( BPy_Camera * self )
853
 
{
854
 
        return PyInt_FromLong( self->camera->id.us );
855
 
}
856
 
 
857
 
 
858
 
static PyObject *Camera_getFakeUser( BPy_Camera * self )
859
 
{
860
 
        if (self->camera->id.flag & LIB_FAKEUSER)
861
 
                Py_RETURN_TRUE;
862
 
        else
863
 
                Py_RETURN_FALSE;
864
 
}
865
 
 
866
 
static int Camera_setFakeUser( BPy_Camera * self, PyObject * value )
867
 
{
868
 
        return SetIdFakeUser(&self->camera->id, value);
869
 
}
870
 
 
871
 
 
872
657
static PyObject *Camera_getType( BPy_Camera * self )
873
658
{
874
659
        if (self->camera->type == EXPP_CAM_TYPE_PERSP)
929
714
 
930
715
static int Camera_setIpo( BPy_Camera * self, PyObject * value )
931
716
{
932
 
        Ipo *ipo = NULL;
933
 
        Ipo *oldipo = self->camera->ipo;
934
 
        ID *id;
935
 
 
936
 
        /* if parameter is not None, check for valid Ipo */
937
 
 
938
 
        if ( value != Py_None ) {
939
 
                if ( !Ipo_CheckPyObject( value ) )
940
 
                        return EXPP_ReturnIntError( PyExc_TypeError,
941
 
                                        "expected an Ipo object" );
942
 
 
943
 
                ipo = Ipo_FromPyObject( value );
944
 
 
945
 
                if( !ipo )
946
 
                        return EXPP_ReturnIntError( PyExc_RuntimeError,
947
 
                                        "null ipo!" );
948
 
 
949
 
                if( ipo->blocktype != ID_CA )
950
 
                        return EXPP_ReturnIntError( PyExc_TypeError,
951
 
                                        "Ipo is not a camera data Ipo" );
952
 
        }
953
 
 
954
 
        /* if already linked to Ipo, delete link */
955
 
 
956
 
        if ( oldipo ) {
957
 
                id = &oldipo->id;
958
 
                if( id->us > 0 )
959
 
                        id->us--;
960
 
        }
961
 
 
962
 
        /* assign new Ipo and increment user count, or set to NULL if deleting */
963
 
 
964
 
        self->camera->ipo = ipo;
965
 
        if ( ipo )
966
 
                id_us_plus(&ipo->id);
967
 
 
968
 
        return 0;
 
717
        return GenericLib_assignData(value, (void **) &self->camera->ipo, 0, 1, ID_IP, ID_CA);
969
718
}
970
719
 
971
720
/*
981
730
        case EXPP_CAM_ATTR_LENS: 
982
731
                param = cam->lens;
983
732
                break;
 
733
        case EXPP_CAM_ATTR_ANGLE: 
 
734
                param = 360.0f * atan(16.0f/cam->lens) / M_PI;
 
735
                break;
984
736
        case EXPP_CAM_ATTR_DOFDIST: 
985
737
                param = cam->YF_dofdist;
986
738
                break;
1025
777
        float *param;
1026
778
        struct Camera *cam = self->camera;
1027
779
        float min, max;
1028
 
 
1029
 
 
 
780
        int ret;
 
781
 
1030
782
        switch( (int)type ) {
1031
783
        case EXPP_CAM_ATTR_LENS:
1032
784
                min = 1.0;
1033
785
                max = 250.0;
1034
786
                param = &cam->lens;
1035
787
                break;
 
788
        case EXPP_CAM_ATTR_ANGLE:
 
789
                min = 7.323871;
 
790
                max = 172.847331;
 
791
                param = &cam->lens;
 
792
                break;
1036
793
        case EXPP_CAM_ATTR_DOFDIST:
1037
794
                min = 0.0;
1038
795
                max = 5000.0;
1049
806
                param = &cam->clipend;
1050
807
                break;
1051
808
        case EXPP_CAM_ATTR_DRAWSIZE:
1052
 
                min = 0.1;
 
809
                min = 0.1f;
1053
810
                max = 10.0;
1054
811
                param = &cam->drawsize;
1055
812
                break;
1056
813
        case EXPP_CAM_ATTR_SCALE:
1057
 
                min = 0.01;
 
814
                min = 0.01f;
1058
815
                max = 1000.0;
1059
816
                param = &cam->ortho_scale;
1060
817
                break;
1079
836
                                "undefined type in setFloatAttrClamp" );
1080
837
        }
1081
838
 
1082
 
        return EXPP_setFloatClamped( value, param, min, max );
 
839
        ret = EXPP_setFloatClamped( value, param, min, max );
 
840
        
 
841
        if (ret==0) {
 
842
                if ((int)type == EXPP_CAM_ATTR_ANGLE) {
 
843
                        cam->lens = 16.0f / tan(M_PI*cam->lens/360.0f);
 
844
                }
 
845
        }
 
846
        return ret;
1083
847
}
1084
848
 
1085
849
 
1095
859
                Py_RETURN_FALSE;
1096
860
}
1097
861
 
1098
 
 
1099
 
 
1100
862
/*
1101
863
 * set floating point attributes which require clamping
1102
864
 */
1115
877
/* Python attributes get/set structure:                                      */
1116
878
/*****************************************************************************/
1117
879
static PyGetSetDef BPy_Camera_getseters[] = {
1118
 
        {"name",
1119
 
         (getter)Camera_getName, (setter)Camera_setName,
1120
 
         "Camera name",
1121
 
         NULL},
1122
 
        {"users",
1123
 
         (getter)Camera_getUsers, (setter)NULL,
1124
 
         "Number of camera users",
1125
 
         NULL},
1126
 
        {"fakeUser",
1127
 
         (getter)Camera_getFakeUser, (setter)Camera_setFakeUser,
1128
 
         "Cameras fake user state",
1129
 
         NULL},
 
880
        GENERIC_LIB_GETSETATTR,
1130
881
        {"type",
1131
882
         (getter)Camera_getType, (setter)Camera_setType,
1132
883
         "camera type \"persp\" or \"ortho\"",
1139
890
         (getter)Camera_getIpo, (setter)Camera_setIpo,
1140
891
         "Cameras ipo",
1141
892
         NULL},
1142
 
         
 
893
        
1143
894
        /* float settings */
1144
895
        {"lens",
1145
896
         (getter)getFloatAttr, (setter)setFloatAttrClamp,
1146
897
         "lens angle for perspective cameras",
1147
898
         (void *)EXPP_CAM_ATTR_LENS},
 
899
        {"angle",
 
900
         (getter)getFloatAttr, (setter)setFloatAttrClamp,
 
901
         "lens angle for perspective cameras",
 
902
         (void *)EXPP_CAM_ATTR_ANGLE},
 
903
         
1148
904
        {"scale",
1149
905
         (getter)getFloatAttr, (setter)setFloatAttrClamp,
1150
906
         "scale for ortho cameras",
1157
913
         (getter)getFloatAttr, (setter)setFloatAttrClamp,
1158
914
         "the cameras clip end",
1159
915
         (void *)EXPP_CAM_ATTR_CLIPEND},
 
916
        {"shiftX",
 
917
         (getter)getFloatAttr, (setter)setFloatAttrClamp,
 
918
         "the cameras X perspective shift",
 
919
         (void *)EXPP_CAM_ATTR_SHIFTX},
 
920
        {"shiftY",
 
921
         (getter)getFloatAttr, (setter)setFloatAttrClamp,
 
922
         "the cameras Y perspective shift",
 
923
         (void *)EXPP_CAM_ATTR_SHIFTY},
1160
924
        {"dofDist",
1161
925
         (getter)getFloatAttr, (setter)setFloatAttrClamp,
1162
926
         "cameras dof distance",
1191
955
         (getter)getFlagAttr, (setter)setFlagAttr,
1192
956
         "toggle the passPartOut display flag",
1193
957
         (void *)CAM_SHOWPASSEPARTOUT},
1194
 
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 
958
        {"angleToggle",
 
959
         (getter)getFlagAttr, (setter)setFlagAttr,
 
960
         "toggle the camera input unit flag",
 
961
         (void *)CAM_ANGLETOGGLE},
 
962
        {NULL,NULL,NULL,NULL}  /* Sentinel */
1195
963
};
1196
964
 
1197
965
 
1208
976
 
1209
977
        /* Methods to implement standard operations */
1210
978
 
1211
 
        ( destructor ) Camera_dealloc,/* destructor tp_dealloc; */
 
979
        NULL,                                           /* destructor tp_dealloc; */
1212
980
        NULL,                       /* printfunc tp_print; */
1213
981
        NULL,                       /* getattrfunc tp_getattr; */
1214
982
        NULL,                       /* setattrfunc tp_setattr; */