33# This file is covered by the GNU General Public License.
44# See the file COPYING for more details.
55import typing
6+ from typing import (
7+ Optional ,
8+ Union ,
9+ )
610
711from comtypes .automation import IEnumVARIANT , VARIANT
812from comtypes import (
2125import itertools
2226import importlib
2327from comInterfaces .tom import ITextDocument
28+ from comInterfaces import Accessibility as IA
2429from comInterfaces import IAccessible2Lib as IA2
2530import tones
2631import languageHandler
@@ -609,17 +614,20 @@ def findOverlayClasses(self,clsList):
609614 if clsList [0 ]== IAccessible and len (clsList )== 3 and self .IAccessibleRole == oleacc .ROLE_SYSTEM_CLIENT and self .childCount == 0 :
610615 clsList .insert (0 ,ContentGenericClient )
611616
612- def __init__ (self ,windowHandle = None ,IAccessibleObject = None ,IAccessibleChildID = None ,event_windowHandle = None ,event_objectID = None ,event_childID = None ):
617+ # C901: 'IAccessible.__init__' is too complex
618+ def __init__ ( # noqa: C901
619+ self ,
620+ windowHandle : Optional [int ] = None ,
621+ IAccessibleObject : Optional [Union [IUnknown , IA .IAccessible , IA2 .IAccessible2 ]] = None ,
622+ IAccessibleChildID : Optional [int ] = None ,
623+ event_windowHandle : Optional = None ,
624+ event_objectID : Optional = None ,
625+ event_childID : Optional = None
626+ ):
627+ """
628+ @param windowHandle: the window handle, if known
629+ @param IAccessibleChildID: A child ID that will be used on all methods of the IAccessible pointer
613630 """
614- @param pacc: a pointer to an IAccessible object
615- @type pacc: ctypes.POINTER(IAccessible)
616- @param child: A child ID that will be used on all methods of the IAccessible pointer
617- @type child: int
618- @param hwnd: the window handle, if known
619- @type hwnd: int
620- @param objectID: the objectID for the IAccessible Object, if known
621- @type objectID: int
622- """
623631 self .IAccessibleObject = IAccessibleObject
624632 self .IAccessibleChildID = IAccessibleChildID
625633
@@ -1484,12 +1492,14 @@ def _get_indexInParent(self):
14841492
14851493 def _get__IA2Relations (self ) -> typing .List [IA2 .IAccessibleRelation ]:
14861494 if not isinstance (self .IAccessibleObject , IA2 .IAccessible2 ):
1495+ log .debug ("Not an IA2.IAccessible2" )
14871496 raise NotImplementedError
14881497 import ctypes
14891498 import comtypes .hresult
14901499 try :
14911500 size = self .IAccessibleObject .nRelations
14921501 except COMError :
1502+ log .debug ("Unable to get nRelations" )
14931503 raise NotImplementedError
14941504 if size <= 0 :
14951505 return list ()
@@ -1498,16 +1508,21 @@ def _get__IA2Relations(self) -> typing.List[IA2.IAccessibleRelation]:
14981508 # The client allocated relations array is an [out] parameter instead of [in, out], so we need to use the raw COM method.
14991509 res = self .IAccessibleObject ._IAccessible2__com__get_relations (size , relations , ctypes .byref (count ))
15001510 if res != comtypes .hresult .S_OK :
1511+ log .debug ("Unable to get relations" )
15011512 raise NotImplementedError
15021513 return list (relations )
15031514
15041515 def _getIA2TargetsForRelationsOfType (
15051516 self ,
15061517 relationType : "IAccessibleHandler.RelationType" ,
15071518 maxRelations : int = 1 ,
1508- ) -> typing .List [ctypes . POINTER ( IUnknown ) ]:
1519+ ) -> typing .List [IUnknown ]:
15091520 """Gets the target IAccessible (actually IUnknown; use QueryInterface or
1510- normalizeIAccessible to resolve) for the relations with given type."""
1521+ normalizeIAccessible to resolve) for the relations with given type.
1522+ Allows escape of exception: COMError(-2147417836, 'Requested object does not exist.'),
1523+ callers should handle this, for this reason consider using _getIA2RelationFirstTarget
1524+ if only the first target is required, and you wish the target to be converted to an IAccessible
1525+ """
15111526 acc = self .IAccessibleObject
15121527 if not isinstance (acc , IA2 .IAccessible2 ):
15131528 raise NotImplementedError
@@ -1548,13 +1563,17 @@ def _getIA2RelationFirstTarget(
15481563 # rather than fetch all the relations and querying the type, do that in process for performance reasons
15491564 targets = self ._getIA2TargetsForRelationsOfType (relationType , maxRelations = 1 )
15501565 if targets :
1551- return targets [0 ]
1566+ ia2Object = IAccessibleHandler .normalizeIAccessible (targets [0 ])
1567+ return IAccessible (
1568+ IAccessibleObject = ia2Object ,
1569+ IAccessibleChildID = 0
1570+ )
15521571 except (NotImplementedError , COMError ):
15531572 log .debugWarning ("Unable to use _getIA2TargetsForRelationsOfType, fallback to _IA2Relations." )
15541573
15551574 # eg IA2_2 is not available, fall back to old approach
1556- for relation in self . _IA2Relations :
1557- try :
1575+ try :
1576+ for relation in self . _IA2Relations :
15581577 if relation .relationType == relationType :
15591578 # Take the first of 'relation.nTargets' see IAccessibleRelation._methods_
15601579 target = relation .target (0 )
@@ -1563,24 +1582,18 @@ def _getIA2RelationFirstTarget(
15631582 IAccessibleObject = ia2Object ,
15641583 IAccessibleChildID = 0
15651584 )
1566- except COMError :
1567- pass
1585+ except (NotImplementedError , COMError ):
1586+ log .debug ("Unable to fetch _IA2Relations" , exc_info = True )
1587+ pass
15681588 return None
15691589
15701590 #: Type definition for auto prop '_get_detailsRelations'
15711591 detailsRelations : typing .Iterable ["IAccessible" ]
15721592
15731593 def _get_detailsRelations (self ) -> typing .Iterable ["IAccessible" ]:
1574- relations = self ._getIA2TargetsForRelationsOfType (
1575- IAccessibleHandler .RelationType .DETAILS ,
1576- maxRelations = 1
1577- )
1578- if not relations :
1594+ relationTarget = self ._getIA2RelationFirstTarget (IAccessibleHandler .RelationType .DETAILS )
1595+ if not relationTarget :
15791596 return ()
1580- relationTarget = IAccessible (
1581- IAccessibleObject = IAccessibleHandler .normalizeIAccessible (relations [0 ]),
1582- IAccessibleChildID = 0
1583- )
15841597 return (relationTarget , )
15851598
15861599 #: Type definition for auto prop '_get_flowsTo'
0 commit comments