@@ -29,6 +29,10 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2929#include "structmember.h"
3030#include "ceval.h"
3131
32+ /* Forward */
33+ static object * class_lookup PROTO ((classobject * , char * , classobject * * ) );
34+ static object * instance_getattr1 PROTO ((instanceobject * , char * ) );
35+
3236object *
3337newclassobject (bases , dict , name )
3438 object * bases ; /* NULL or tuple of classobjects! */
@@ -37,7 +41,7 @@ newclassobject(bases, dict, name)
3741{
3842 int pos ;
3943 object * key , * value ;
40- classobject * op ;
44+ classobject * op , * dummy ;
4145 if (bases == NULL ) {
4246 bases = newtupleobject (0 );
4347 if (bases == NULL )
@@ -55,6 +59,12 @@ newclassobject(bases, dict, name)
5559 op -> cl_dict = dict ;
5660 XINCREF (name );
5761 op -> cl_name = name ;
62+ op -> cl_getattr = class_lookup (op , "__getattr__" , & dummy );
63+ op -> cl_setattr = class_lookup (op , "__setattr__" , & dummy );
64+ op -> cl_delattr = class_lookup (op , "__delattr__" , & dummy );
65+ XINCREF (op -> cl_getattr );
66+ XINCREF (op -> cl_setattr );
67+ XINCREF (op -> cl_delattr );
5868 pos = 0 ;
5969 while (mappinggetnext (dict , & pos , & key , & value )) {
6070 if (is_accessobject (value ))
@@ -223,8 +233,6 @@ issubclass(class, base)
223233
224234/* Instance objects */
225235
226- static object * instance_getattr PROTO ((instanceobject * , char * ) );
227-
228236static int
229237addaccess (class , inst )
230238 classobject * class ;
@@ -285,7 +293,7 @@ newinstanceobject(class, arg)
285293 DECREF (inst );
286294 return NULL ;
287295 }
288- init = instance_getattr (inst , "__init__" );
296+ init = instance_getattr1 (inst , "__init__" );
289297 if (init == NULL ) {
290298 err_clear ();
291299 if (arg != NULL && !(is_tupleobject (arg ) &&
@@ -328,7 +336,7 @@ instance_dealloc(inst)
328336 revive the object and save the current exception, if any. */
329337 INCREF (inst );
330338 err_get (& error_type , & error_value );
331- if ((del = instance_getattr (inst , "__del__" )) != NULL ) {
339+ if ((del = instance_getattr1 (inst , "__del__" )) != NULL ) {
332340 object * args = newtupleobject (0 );
333341 object * res = args ;
334342 if (res != NULL )
@@ -348,76 +356,6 @@ instance_dealloc(inst)
348356 free ((ANY * )inst );
349357}
350358
351- static object * instance_getattr1 ();
352- static int instance_setattr1 ();
353-
354- static object *
355- instance_getslot_meth (self , args )
356- instanceobject * self ;
357- object * args ;
358- {
359- object * v ;
360- char * name ;
361- if (!getargs (args , "s" , & name ))
362- return NULL ;
363- return instance_getattr1 (self , name );
364- }
365-
366- static object *
367- instance_hasslot_meth (self , args )
368- instanceobject * self ;
369- object * args ;
370- {
371- object * v ;
372- char * name ;
373- if (!getargs (args , "s" , & name ))
374- return NULL ;
375- v = instance_getattr1 (self , name );
376- if (v == NULL ) {
377- err_clear ();
378- return newintobject (0L );
379- }
380- DECREF (v );
381- return newintobject (1L );
382- }
383-
384- static object *
385- instance_setslot_meth (self , args )
386- instanceobject * self ;
387- object * args ;
388- {
389- char * name ;
390- object * value ;
391- value = NULL ;
392- if (!getargs (args , "s" , & name )) {
393- err_clear ();
394- if (!getargs (args , "(sO)" , & name , & value ))
395- return NULL ;
396- }
397- if (instance_setattr1 (self , name , value )< 0 ) {
398- return NULL ;
399- }
400- INCREF (None );
401- return None ;
402- }
403-
404- static object *
405- instance_delslot_meth (self , args )
406- instanceobject * self ;
407- object * args ;
408- {
409- char * name ;
410- if (!getargs (args , "s" , & name )) {
411- return NULL ;
412- }
413- if (instance_setattr1 (self , name , 0 )< 0 ) {
414- return NULL ;
415- }
416- INCREF (None );
417- return None ;
418- }
419-
420-
421359static object *
422360instance_getattr1 (inst , name )
423361 register instanceobject * inst ;
@@ -479,59 +417,23 @@ instance_getattr(inst, name)
479417 register char * name ;
480418{
481419 register object * func , * res ;
482- if (name [0 ] == '_' && name [1 ] == '_' ) {
483- /* Let's not compare the first "__": */
484- /* use &name[2] :-) */
485- if (strcmp (& name [2 ], "setslot__" ) == 0 ) {
486- return newmethodobject (name ,
487- (method )instance_setslot_meth ,
488- (object * )inst ,
489- 0 );
490- }
491- if (strcmp (& name [2 ], "getslot__" ) == 0 ) {
492- return newmethodobject (name ,
493- (method )instance_getslot_meth ,
494- (object * )inst ,
495- 0 );
496- }
497- if (strcmp (& name [2 ], "hasslot__" ) == 0 ) {
498- return newmethodobject (name ,
499- (method )instance_hasslot_meth ,
500- (object * )inst ,
501- 0 );
502- }
503- if (strcmp (& name [2 ], "delslot__" ) == 0 ) {
504- return newmethodobject (name ,
505- (method )instance_delslot_meth ,
506- (object * )inst ,
507- 0 );
508- }
509- /* The following methods should not be forwarded! */
510- if ( strcmp (& name [2 ], "init__" ) == 0
511- || strcmp (& name [2 ], "del__" ) == 0 ) {
512- return instance_getattr1 (inst ,name );
420+ res = instance_getattr1 (inst , name );
421+ if (res == NULL && (func = inst -> in_class -> cl_getattr ) != NULL ) {
422+ object * args ;
423+ #if 0
424+ if (name [0 ] == '_' && name [1 ] == '_' ) {
425+ int n = strlen (name );
426+ if (name [n - 1 ] == '_' && name [n - 2 ] == '_' ) {
427+ /* Don't mess with system attributes */
428+ return NULL ;
429+ }
513430 }
514- }
515- res = instance_getattr1 (inst ,name );
516- if (res == NULL ) {
517- /* Self doesn't have this attribute, */
518- /* so let's try to call self.__getattr__(name) */
519- object * func ;
520- object * arg ;
521- /* Well, lets get a funcobject for __getattr__ ...*/
522- func = instance_getattr1 (inst ,"__getattr__" );
523- if (func == NULL ) {
524- /* OOPS, we don't have a __getattr__. */
525- /* Set the error ... */
526- err_clear ();
527- err_setstr (AttributeError , name );
431+ #endif
432+ args = mkvalue ("(Os)" , inst , name );
433+ if (args == NULL )
528434 return NULL ;
529- }
530- arg = newstringobject (name );
531- /*... and call it */
532- res = call_object (func ,arg );
533- DECREF (arg );
534- DECREF (func );
435+ res = call_object (func , args );
436+ DECREF (args );
535437 }
536438 return res ;
537439}
@@ -543,13 +445,6 @@ instance_setattr1(inst, name, v)
543445 object * v ;
544446{
545447 object * ac ;
546- if (name [0 ] == '_' && name [1 ] == '_' ) {
547- int n = strlen (name );
548- if (name [n - 1 ] == '_' && name [n - 2 ] == '_' ) {
549- err_setstr (TypeError , "read-only special attribute" );
550- return -1 ;
551- }
552- }
553448 ac = dictlookup (inst -> in_dict , name );
554449 if (ac != NULL && is_accessobject (ac ))
555450 return setaccessvalue (ac , getowner (), v );
@@ -570,49 +465,31 @@ instance_setattr(inst, name, v)
570465 char * name ;
571466 object * v ;
572467{
573- object * ac , * func ;
574- classobject * class ;
575- char * setattrname ;
576- /* I think I saw something in the news, that deletion of an attribute */
577- /* is done by setattr with the value being NULL. */
578- /* Let's be prepared for this case :-)*/
579- if (v != NULL )
580- setattrname = "__setattr__" ;
581- else
582- setattrname = "__delattr__" ;
583-
584- /* Here is the only performance loss: */
585- /* We have to check if there is a method __setattr__.*/
586- /* Only class can have a __setattr__ because it's forbidden to */
587- /* assign to self.__setattr__.*/
588- /* So, lets do a class_lookup which is (hopefully) cheap */
589- class = NULL ;
590- func = class_lookup (inst -> in_class , setattrname , & class );
591- if (func == NULL ) {
592- /* Call the original instance_setattr */
593- return instance_setattr1 (inst ,name ,v );
594- } else {
595- object * arg , * res ;
596- /* class_lookup did'nt REF(func) - so we won't UNREF(func). */
597- /* Let's get the function (could be optimized....) */
598- func = instance_getattr (inst ,setattrname );
599- if (func == 0 )
600- return -1 ;
601- /* Deleting an attribute is done by v==NULL */
602- if (v == NULL )
603- /* __delattr__ has only one argument: the name */
604- arg = mkvalue ("s" ,name );
605- else
606- arg = mkvalue ("(sO)" ,name ,v );
607- res = call_object (func ,arg );
608- DECREF (func );
609- DECREF (arg );
610- if (res == NULL ) {
611- /* Oops, something went wrong :-( */
468+ object * func , * args , * res ;
469+ if (name [0 ] == '_' && name [1 ] == '_' ) {
470+ int n = strlen (name );
471+ if (name [n - 1 ] == '_' && name [n - 2 ] == '_' ) {
472+ err_setstr (TypeError , "read-only special attribute" );
612473 return -1 ;
613474 }
614- DECREF (res );
615475 }
476+ if (v == NULL )
477+ func = inst -> in_class -> cl_delattr ;
478+ else
479+ func = inst -> in_class -> cl_setattr ;
480+ if (func == NULL )
481+ return instance_setattr1 (inst , name , v );
482+ if (v == NULL )
483+ args = mkvalue ("(Os)" , inst , name );
484+ else
485+ args = mkvalue ("(OsO)" , inst , name , v );
486+ if (args == NULL )
487+ return -1 ;
488+ res = call_object (func , args );
489+ DECREF (args );
490+ if (res == NULL )
491+ return -1 ;
492+ DECREF (res );
616493 return 0 ;
617494}
618495
@@ -1107,7 +984,7 @@ static number_methods instance_as_number = {
1107984 (binaryfunc )instance_div , /*nb_divide*/
1108985 (binaryfunc )instance_mod , /*nb_remainder*/
1109986 (binaryfunc )instance_divmod , /*nb_divmod*/
1110- (binaryfunc )instance_pow , /*nb_power*/
987+ (ternaryfunc )instance_pow , /*nb_power*/
1111988 (unaryfunc )instance_neg , /*nb_negative*/
1112989 (unaryfunc )instance_pos , /*nb_positive*/
1113990 (unaryfunc )instance_abs , /*nb_absolute*/
0 commit comments