@@ -515,7 +515,12 @@ def _get_good_object_(obj, obUserName=None, resultCLSID=None):
515515class CoClassBaseClass :
516516 def __init__ (self , oobj = None ):
517517 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+
519524 def __repr__ (self ):
520525 return "<win32com.gen_py.%s.%s>" % (__doc__ , self .__class__ .__name__ )
521526
@@ -535,22 +540,25 @@ def __setattr__(self, attr, value):
535540 self .__dict__ [attr ] = value
536541
537542 # 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 ):
541550 return self .__dict__ ["_dispobj_" ].__call__ (* args , ** kwargs )
542- def __str__ (self , * args ):
551+ def __maybe__str__ (self , * args ):
543552 return self .__dict__ ["_dispobj_" ].__str__ (* args )
544- def __int__ (self , * args ):
553+ def __maybe__int__ (self , * args ):
545554 return self .__dict__ ["_dispobj_" ].__int__ (* args )
546- def __iter__ (self ):
555+ def __maybe__iter__ (self ):
547556 return self .__dict__ ["_dispobj_" ].__iter__ ()
548- def __len__ (self ):
557+ def __maybe__len__ (self ):
549558 return self .__dict__ ["_dispobj_" ].__len__ ()
550- def __nonzero__ (self ):
559+ def __maybe__nonzero__ (self ):
551560 return self .__dict__ ["_dispobj_" ].__nonzero__ ()
552561
553-
554562# A very simple VARIANT class. Only to be used with poorly-implemented COM
555563# objects. If an object accepts an arg which is a simple "VARIANT", but still
556564# is very pickly about the actual variant type (eg, isn't happy with a VT_I4,
0 commit comments