@@ -515,7 +515,12 @@ def _get_good_object_(obj, obUserName=None, resultCLSID=None):
515
515
class CoClassBaseClass :
516
516
def __init__ (self , oobj = None ):
517
517
if oobj is None : oobj = pythoncom .new (self .CLSID )
518
- self .__dict__ ["_dispobj_" ] = self .default_interface (oobj )
518
+ dispobj = self .__dict__ ["_dispobj_" ] = self .default_interface (oobj )
519
+ # See comments below re the special methods.
520
+ for maybe in ["__call__" , "__str__" , "__int__" , "__iter__" , "__len__" , "__nonzero__" ]:
521
+ if hasattr (dispobj , maybe ):
522
+ setattr (self , maybe , getattr (self , "__maybe" + maybe ))
523
+
519
524
def __repr__ (self ):
520
525
return "<win32com.gen_py.%s.%s>" % (__doc__ , self .__class__ .__name__ )
521
526
@@ -535,22 +540,25 @@ def __setattr__(self, attr, value):
535
540
self .__dict__ [attr ] = value
536
541
537
542
# Special methods don't use __getattr__ etc, so explicitly delegate here.
538
- # Some wrapped objects might not have them, but that's OK - the attribute
539
- # error can just bubble up.
540
- def __call__ (self , * args , ** kwargs ):
543
+ # Note however, that not all are safe to let bubble up - things like
544
+ # `bool(ob)` will break if the object defines __int__ but then raises an
545
+ # attribute error - eg, see #1753.
546
+ # It depends on what the wrapped COM object actually defines whether these
547
+ # will exist on the underlying object, so __init__ explicitly checks if they
548
+ # do and if so, wires them up.
549
+ def __maybe__call__ (self , * args , ** kwargs ):
541
550
return self .__dict__ ["_dispobj_" ].__call__ (* args , ** kwargs )
542
- def __str__ (self , * args ):
551
+ def __maybe__str__ (self , * args ):
543
552
return self .__dict__ ["_dispobj_" ].__str__ (* args )
544
- def __int__ (self , * args ):
553
+ def __maybe__int__ (self , * args ):
545
554
return self .__dict__ ["_dispobj_" ].__int__ (* args )
546
- def __iter__ (self ):
555
+ def __maybe__iter__ (self ):
547
556
return self .__dict__ ["_dispobj_" ].__iter__ ()
548
- def __len__ (self ):
557
+ def __maybe__len__ (self ):
549
558
return self .__dict__ ["_dispobj_" ].__len__ ()
550
- def __nonzero__ (self ):
559
+ def __maybe__nonzero__ (self ):
551
560
return self .__dict__ ["_dispobj_" ].__nonzero__ ()
552
561
553
-
554
562
# A very simple VARIANT class. Only to be used with poorly-implemented COM
555
563
# objects. If an object accepts an arg which is a simple "VARIANT", but still
556
564
# is very pickly about the actual variant type (eg, isn't happy with a VT_I4,
0 commit comments