@property<EOL><INDENT>def StyleId(self) -> int:<DEDENT>

return self.pattern.CurrentStyleId<EOL>

Property StyleId.
Call IUIAutomationStylesPattern::get_CurrentStyleId.
Return int, a value in class `StyleId`, the visual style associated with an element in a document.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationstylespattern-get_currentstyleid


@property<EOL><INDENT>def StyleName(self) -> str:<DEDENT>

return self.pattern.CurrentStyleName<EOL>

Property StyleName.
Call IUIAutomationStylesPattern::get_CurrentStyleName.
Return str, the name of the visual style associated with an element in a document.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationstylespattern-get_currentstylename


self.pattern = pattern<EOL>


return self.pattern.Cancel() == S_OK<EOL>

Call IUIAutomationSynchronizedInputPattern::Cancel.
Cause the Microsoft UI Automation provider to stop listening for mouse or keyboard input.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationsynchronizedinputpattern-cancel


return self.pattern.StartListening() == S_OK<EOL>

Call IUIAutomationSynchronizedInputPattern::StartListening.
Cause the Microsoft UI Automation provider to start listening for mouse or keyboard input.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationsynchronizedinputpattern-startlistening


eleArray = self.pattern.GetCurrentColumnHeaderItems()<EOL>if eleArray:<EOL><INDENT>controls = []<EOL>for i in range(eleArray.Length):<EOL><INDENT>ele = eleArray.GetElement(i)<EOL>con = Control.CreateControlFromElement(element=ele)<EOL>if con:<EOL><INDENT>controls.append(con)<EOL><DEDENT><DEDENT>return controls<EOL><DEDENT>return []<EOL>

Call IUIAutomationTableItemPattern::GetCurrentColumnHeaderItems.
Return list, a list of `Control` subclasses, the column headers associated with a table item or cell.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtableitempattern-getcurrentcolumnheaderitems


eleArray = self.pattern.GetCurrentRowHeaderItems()<EOL>if eleArray:<EOL><INDENT>controls = []<EOL>for i in range(eleArray.Length):<EOL><INDENT>ele = eleArray.GetElement(i)<EOL>con = Control.CreateControlFromElement(element=ele)<EOL>if con:<EOL><INDENT>controls.append(con)<EOL><DEDENT><DEDENT>return controls<EOL><DEDENT>return []<EOL>

Call IUIAutomationTableItemPattern::GetCurrentRowHeaderItems.
Return list, a list of `Control` subclasses, the row headers associated with a table item or cell.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtableitempattern-getcurrentrowheaderitems


@property<EOL><INDENT>def RowOrColumnMajor(self) -> int:<DEDENT>

return self.pattern.CurrentRowOrColumnMajor<EOL>

Property RowOrColumnMajor.
Call IUIAutomationTablePattern::get_CurrentRowOrColumnMajor.
Return int, a value in class `RowOrColumnMajor`, the primary direction of traversal for the table.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtablepattern-get_currentroworcolumnmajor


eleArray = self.pattern.GetCurrentColumnHeaders()<EOL>if eleArray:<EOL><INDENT>controls = []<EOL>for i in range(eleArray.Length):<EOL><INDENT>ele = eleArray.GetElement(i)<EOL>con = Control.CreateControlFromElement(element=ele)<EOL>if con:<EOL><INDENT>controls.append(con)<EOL><DEDENT><DEDENT>return controls<EOL><DEDENT>return []<EOL>

Call IUIAutomationTablePattern::GetCurrentColumnHeaders.
Return list, a list of `Control` subclasses, representing all the column headers in a table..
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtablepattern-getcurrentcolumnheaders


eleArray = self.pattern.GetCurrentRowHeaders()<EOL>if eleArray:<EOL><INDENT>controls = []<EOL>for i in range(eleArray.Length):<EOL><INDENT>ele = eleArray.GetElement(i)<EOL>con = Control.CreateControlFromElement(element=ele)<EOL>if con:<EOL><INDENT>controls.append(con)<EOL><DEDENT><DEDENT>return controls<EOL><DEDENT>return []<EOL>

Call IUIAutomationTablePattern::GetCurrentRowHeaders.
Return list, a list of `Control` subclasses, representing all the row headers in a table.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtablepattern-getcurrentrowheaders


self.textRange = textRange<EOL>


def AddToSelection(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.textRange.AddToSelection() == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTextRange::AddToSelection.
Add the text range to the collection of selected text ranges in a control that supports multiple, disjoint spans of selected text.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-addtoselection


return TextRange(textRange=self.textRange.Clone())<EOL>

Call IUIAutomationTextRange::Clone.
return `TextRange`, identical to the original and inheriting all properties of the original.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-clone


def Compare(self, textRange: '<STR_LIT>') -> bool:

return bool(self.textRange.Compare(textRange.textRange))<EOL>

Call IUIAutomationTextRange::Compare.
textRange: `TextRange`.
Return bool, specifies whether this text range has the same endpoints as another text range.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-compare


def CompareEndpoints(self, srcEndPoint: int, textRange: '<STR_LIT>', targetEndPoint: int) -> int:

return self.textRange.CompareEndpoints(srcEndPoint, textRange, targetEndPoint)<EOL>

Call IUIAutomationTextRange::CompareEndpoints.
srcEndPoint: int, a value in class `TextPatternRangeEndpoint`.
textRange: `TextRange`.
targetEndPoint: int, a value in class `TextPatternRangeEndpoint`.
Return int, a negative value if the caller's endpoint occurs earlier in the text than the target endpoint;
            0 if the caller's endpoint is at the same location as the target endpoint;
            or a positive value if the caller's endpoint occurs later in the text than the target endpoint.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-compareendpoints


def ExpandToEnclosingUnit(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.textRange.ExpandToEnclosingUnit() == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTextRange::ExpandToEnclosingUnit.
Normalize the text range by the specified text unit.
    The range is expanded if it is smaller than the specified unit,
    or shortened if it is longer than the specified unit.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-expandtoenclosingunit


def FindAttribute(self, textAttributeId: int, val, backward: bool) -> '<STR_LIT>':

textRange = self.textRange.FindAttribute(textAttributeId, val, int(backward))<EOL>if textRange:<EOL><INDENT>return TextRange(textRange=textRange)<EOL><DEDENT>

Call IUIAutomationTextRange::FindAttribute.
textAttributeID: int, a value in class `TextAttributeId`.
val: COM VARIANT according to textAttributeId? todo.
backward: bool, True if the last occurring text range should be returned instead of the first; otherwise False.
return `TextRange` or None, a text range subset that has the specified text attribute value.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-findattribute


def FindText(self, text: str, backward: bool, ignoreCase: bool) -> '<STR_LIT>':

textRange = self.textRange.FindText(text, int(backward), int(ignoreCase))<EOL>if textRange:<EOL><INDENT>return TextRange(textRange=textRange)<EOL><DEDENT>

Call IUIAutomationTextRange::FindText.
text: str,
backward: bool, True if the last occurring text range should be returned instead of the first; otherwise False.
ignoreCase: bool, True if case should be ignored; otherwise False.
return `TextRange` or None, a text range subset that contains the specified text.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-findtext


def GetAttributeValue(self, textAttributeId: int) -> ctypes.POINTER(comtypes.IUnknown):

return self.textRange.GetAttributeValue(textAttributeId)<EOL>

Call IUIAutomationTextRange::GetAttributeValue.
textAttributeId: int, a value in class `TextAttributeId`.
Return `ctypes.POINTER(comtypes.IUnknown)` or None, the value of the specified text attribute across the entire text range, todo.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-getattributevalue


def GetBoundingRectangles(self) -> list:

floats = self.textRange.GetBoundingRectangles()<EOL>rects = []<EOL>for i in range(len(floats) // <NUM_LIT:4>):<EOL><INDENT>rect = Rect(int(floats[i * <NUM_LIT:4>]), int(floats[i * <NUM_LIT:4> + <NUM_LIT:1>]),<EOL>int(floats[i * <NUM_LIT:4>]) + int(floats[i * <NUM_LIT:4> + <NUM_LIT:2>]), int(floats[i * <NUM_LIT:4> + <NUM_LIT:1>]) + int(floats[i * <NUM_LIT:4> + <NUM_LIT:3>]))<EOL>rects.append(rect)<EOL><DEDENT>return rects<EOL>

Call IUIAutomationTextRange::GetBoundingRectangles.
textAttributeId: int, a value in class `TextAttributeId`.
Return list, a list of `Rect`.
    bounding rectangles for each fully or partially visible line of text in a text range..
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-getboundingrectangles

for rect in textRange.GetBoundingRectangles():
    print(rect.left, rect.top, rect.right, rect.bottom, rect.width(), rect.height(), rect.xcenter(), rect.ycenter())


eleArray = self.textRange.GetChildren()<EOL>if eleArray:<EOL><INDENT>controls = []<EOL>for i in range(eleArray.Length):<EOL><INDENT>ele = eleArray.GetElement(i)<EOL>con = Control.CreateControlFromElement(element=ele)<EOL>if con:<EOL><INDENT>controls.append(con)<EOL><DEDENT><DEDENT>return controls<EOL><DEDENT>return []<EOL>

Call IUIAutomationTextRange::GetChildren.
textAttributeId: int, a value in class `TextAttributeId`.
Return list, a list of `Control` subclasses, embedded objects that fall within the text range..
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-getchildren


def GetEnclosingControl(self) -> '<STR_LIT>':

return Control.CreateControlFromElement(self.textRange.GetEnclosingElement())<EOL>

Call IUIAutomationTextRange::GetEnclosingElement.
Return `Control` subclass, the innermost UI Automation element that encloses the text range.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-getenclosingelement


def GetText(self, maxLength: int = -<NUM_LIT:1>) -> str:

return self.textRange.GetText(maxLength)<EOL>

Call IUIAutomationTextRange::GetText.
maxLength: int, the maximum length of the string to return, or -1 if no limit is required.
Return str, the plain text of the text range.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-gettext


def Move(self, unit: int, count: int, waitTime: float = OPERATION_WAIT_TIME) -> int:

ret = self.textRange.Move(unit, count)<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTextRange::Move.
Move the text range forward or backward by the specified number of text units.
unit: int, a value in class `TextUnit`.
count: int, the number of text units to move.
       A positive value moves the text range forward.
       A negative value moves the text range backward. Zero has no effect.
waitTime: float.
Return: int, the number of text units actually moved.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-move


def MoveEndpointByRange(self, srcEndPoint: int, textRange: '<STR_LIT>', targetEndPoint: int, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.textRange.MoveEndpointByRange(srcEndPoint, textRange.textRange, targetEndPoint) == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTextRange::MoveEndpointByRange.
Move one endpoint of the current text range to the specified endpoint of a second text range.
srcEndPoint: int, a value in class `TextPatternRangeEndpoint`.
textRange: `TextRange`.
targetEndPoint: int, a value in class `TextPatternRangeEndpoint`.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-moveendpointbyrange


def MoveEndpointByUnit(self, endPoint: int, unit: int, count: int, waitTime: float = OPERATION_WAIT_TIME) -> int:

ret = self.textRange.MoveEndpointByUnit(endPoint, unit, count)<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTextRange::MoveEndpointByUnit.
Move one endpoint of the text range the specified number of text units within the document range.
endPoint: int, a value in class `TextPatternRangeEndpoint`.
unit: int, a value in class `TextUnit`.
count: int, the number of units to move.
            A positive count moves the endpoint forward.
            A negative count moves backward.
            A count of 0 has no effect.
waitTime: float.
Return int, the count of units actually moved.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-moveendpointbyunit


def RemoveFromSelection(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.textRange.RemoveFromSelection() == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTextRange::RemoveFromSelection.
Remove the text range from an existing collection of selected text in a text container that supports multiple, disjoint selections.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-removefromselection


def ScrollIntoView(self, alignTop: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.textRange.ScrollIntoView(int(alignTop)) == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTextRange::ScrollIntoView.
Cause the text control to scroll until the text range is visible in the viewport.
alignTop: bool, True if the text control should be scrolled so that the text range is flush with the top of the viewport;
                False if it should be flush with the bottom of the viewport.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-scrollintoview


def Select(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.textRange.Select() == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTextRange::Select.
Select the span of text that corresponds to this text range, and remove any previous selection.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-select


self.pattern = pattern<EOL>


@property<EOL><INDENT>def TextContainer(self) -> '<STR_LIT>':<DEDENT>

return Control.CreateControlFromElement(self.pattern.TextContainer)<EOL>

Property TextContainer.
Call IUIAutomationSelectionContainer::get_TextContainer.
Return `Control` subclass, the nearest ancestor element that supports the Text control pattern.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextchildpattern-get_textcontainer


@property<EOL><INDENT>def TextRange(self) -> TextRange:<DEDENT>

return TextRange(self.pattern.TextRange)<EOL>

Property TextRange.
Call IUIAutomationSelectionContainer::get_TextRange.
Return `TextRange`, a text range that encloses this child element.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextchildpattern-get_textrange


def GetActiveComposition(self) -> TextRange:

textRange = self.pattern.GetActiveComposition()<EOL>if textRange:<EOL><INDENT>return TextRange(textRange=textRange)<EOL><DEDENT>

Call IUIAutomationTextEditPattern::GetActiveComposition.
Return `TextRange` or None, the active composition.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtexteditpattern-getactivecomposition


def GetConversionTarget(self) -> TextRange:

textRange = self.pattern.GetConversionTarget()<EOL>if textRange:<EOL><INDENT>return TextRange(textRange=textRange)<EOL><DEDENT>

Call IUIAutomationTextEditPattern::GetConversionTarget.
Return `TextRange` or None, the current conversion target range..
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtexteditpattern-getconversiontarget


@property<EOL><INDENT>def DocumentRange(self) -> TextRange:<DEDENT>

return TextRange(self.pattern.DocumentRange)<EOL>

Property DocumentRange.
Call IUIAutomationTextPattern::get_DocumentRange.
Return `TextRange`, a text range that encloses the main text of a document.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextpattern-get_documentrange


@property<EOL><INDENT>def SupportedTextSelection(self) -> bool:<DEDENT>

return bool(self.pattern.SupportedTextSelection)<EOL>

Property SupportedTextSelection.
Call IUIAutomationTextPattern::get_SupportedTextSelection.
Return bool, specifies the type of text selection that is supported by the control.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextpattern-get_supportedtextselection


eleArray = self.pattern.GetSelection()<EOL>if eleArray:<EOL><INDENT>textRanges = []<EOL>for i in range(eleArray.Length):<EOL><INDENT>ele = eleArray.GetElement(i)<EOL>textRanges.append(TextRange(textRange=ele))<EOL><DEDENT>return textRanges<EOL><DEDENT>return []<EOL>

Call IUIAutomationTextPattern::GetSelection.
Return list, a list of `TextRange`, represents the currently selected text in a text-based control.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextpattern-getselection


eleArray = self.pattern.GetVisibleRanges()<EOL>if eleArray:<EOL><INDENT>textRanges = []<EOL>for i in range(eleArray.Length):<EOL><INDENT>ele = eleArray.GetElement(i)<EOL>textRanges.append(TextRange(textRange=ele))<EOL><DEDENT>return textRanges<EOL><DEDENT>return []<EOL>

Call IUIAutomationTextPattern::GetVisibleRanges.
Return list, a list of `TextRange`, disjoint text ranges from a text-based control
             where each text range represents a contiguous span of visible text.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextpattern-getvisibleranges


def RangeFromChild(self, child) -> TextRange:

textRange = self.pattern.RangeFromChild(Control.Element)<EOL>if textRange:<EOL><INDENT>return TextRange(textRange=textRange)<EOL><DEDENT>

Call IUIAutomationTextPattern::RangeFromChild.
child: `Control` or its subclass.
Return `TextRange` or None, a text range enclosing a child element such as an image,
    hyperlink, Microsoft Excel spreadsheet, or other embedded object.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextpattern-rangefromchild


def RangeFromPoint(self, x: int, y: int) -> TextRange:

textRange = self.pattern.RangeFromPoint(ctypes.wintypes.POINT(x, y))<EOL>if textRange:<EOL><INDENT>return TextRange(textRange=textRange)<EOL><DEDENT>

Call IUIAutomationTextPattern::RangeFromPoint.
child: `Control` or its subclass.
Return `TextRange` or None, the degenerate (empty) text range nearest to the specified screen coordinates.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextpattern-rangefrompoint


@property<EOL><INDENT>def ToggleState(self) -> int:<DEDENT>

return self.pattern.CurrentToggleState<EOL>

Property ToggleState.
Call IUIAutomationTogglePattern::get_CurrentToggleState.
Return int, a value in class `ToggleState`, the state of the control.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtogglepattern-get_currenttogglestate


def Toggle(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.Toggle() == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTogglePattern::Toggle.
Cycle through the toggle states of the control.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtogglepattern-toggle


@property<EOL><INDENT>def CanMove(self) -> bool:<DEDENT>

return bool(self.pattern.CurrentCanMove)<EOL>

Property CanMove.
Call IUIAutomationTransformPattern::get_CurrentCanMove.
Return bool, indicates whether the element can be moved.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern-get_currentcanmove


@property<EOL><INDENT>def CanResize(self) -> bool:<DEDENT>

return bool(self.pattern.CurrentCanResize)<EOL>

Property CanResize.
Call IUIAutomationTransformPattern::get_CurrentCanResize.
Return bool, indicates whether the element can be resized.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern-get_currentcanresize


@property<EOL><INDENT>def CanRotate(self) -> bool:<DEDENT>

return bool(self.pattern.CurrentCanRotate)<EOL>

Property CanRotate.
Call IUIAutomationTransformPattern::get_CurrentCanRotate.
Return bool, indicates whether the element can be rotated.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern-get_currentcanrotate


def Move(self, x: int, y: int, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.Move(x, y) == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTransformPattern::Move.
Move the UI Automation element.
x: int.
y: int.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern-move


def Resize(self, width: int, height: int, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.Resize(width, height) == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTransformPattern::Resize.
Resize the UI Automation element.
width: int.
height: int.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern-resize


def Rotate(self, degrees: int, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.Rotate(degrees) == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTransformPattern::Rotate.
Rotates the UI Automation element.
degrees: int.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern-rotate


self.pattern = pattern<EOL>


@property<EOL><INDENT>def CanZoom(self) -> bool:<DEDENT>

return bool(self.pattern.CurrentCanZoom)<EOL>

Property CanZoom.
Call IUIAutomationTransformPattern2::get_CurrentCanZoom.
Return bool, indicates whether the control supports zooming of its viewport.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern2-get_CurrentCanZoom


@property<EOL><INDENT>def ZoomLevel(self) -> float:<DEDENT>

return self.pattern.CurrentZoomLevel<EOL>

Property ZoomLevel.
Call IUIAutomationTransformPattern2::get_CurrentZoomLevel.
Return float, the zoom level of the control's viewport.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern2-get_currentzoomlevel


@property<EOL><INDENT>def ZoomMaximum(self) -> float:<DEDENT>

return self.pattern.CurrentZoomMaximum<EOL>

Property ZoomMaximum.
Call IUIAutomationTransformPattern2::get_CurrentZoomMaximum.
Return float, the maximum zoom level of the control's viewport.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern2-get_currentzoommaximum


@property<EOL><INDENT>def ZoomMinimum(self) -> float:<DEDENT>

return self.pattern.CurrentZoomMinimum<EOL>

Property ZoomMinimum.
Call IUIAutomationTransformPattern2::get_CurrentZoomMinimum.
Return float, the minimum zoom level of the control's viewport.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern2-get_currentzoomminimum


def Zoom(self, zoomLevel: float, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.Zoom(zoomLevel) == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTransformPattern2::Zoom.
Zoom the viewport of the control.
zoomLevel: float for int.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern2-zoom


def ZoomByUnit(self, zoomUnit: int, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.ZoomByUnit(zoomUnit) == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTransformPattern2::ZoomByUnit.
Zoom the viewport of the control by the specified unit.
zoomUnit: int, a value in class `ZoomUnit`.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationtransformpattern2-zoombyunit


@property<EOL><INDENT>def IsReadOnly(self) -> bool:<DEDENT>

return self.pattern.CurrentIsReadOnly<EOL>

Property IsReadOnly.
Call IUIAutomationTransformPattern2::IUIAutomationValuePattern::get_CurrentIsReadOnly.
Return bool, indicates whether the value of the element is read-only.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationvaluepattern-get_currentisreadonly


@property<EOL><INDENT>def Value(self) -> str:<DEDENT>

return self.pattern.CurrentValue<EOL>

Property Value.
Call IUIAutomationTransformPattern2::IUIAutomationValuePattern::get_CurrentValue.
Return str, the value of the element.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationvaluepattern-get_currentvalue


def SetValue(self, value: str, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.SetValue(value) == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationTransformPattern2::IUIAutomationValuePattern::SetValue.
Set the value of the element.
value: str.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationvaluepattern-setvalue


def Realize(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.Realize() == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationVirtualizedItemPattern::Realize.
Create a full UI Automation element for a virtualized item.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationvirtualizeditempattern-realize


def Close(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.Close() == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationWindowPattern::Close.
Close the window.
waitTime: float.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationwindowpattern-close


@property<EOL><INDENT>def CanMaximize(self) -> bool:<DEDENT>

return bool(self.pattern.CurrentCanMaximize)<EOL>

Property CanMaximize.
Call IUIAutomationWindowPattern::get_CurrentCanMaximize.
Return bool, indicates whether the window can be maximized.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationwindowpattern-get_currentcanmaximize


@property<EOL><INDENT>def CanMinimize(self) -> bool:<DEDENT>

return bool(self.pattern.CurrentCanMinimize)<EOL>

Property CanMinimize.
Call IUIAutomationWindowPattern::get_CurrentCanMinimize.
Return bool, indicates whether the window can be minimized.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationwindowpattern-get_currentismodal


@property<EOL><INDENT>def IsModal(self) -> bool:<DEDENT>

return bool(self.pattern.CurrentIsModal)<EOL>

Property IsModal.
Call IUIAutomationWindowPattern::get_CurrentIsModal.
Return bool, indicates whether the window is modal.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationwindowpattern-get_currentistopmost


@property<EOL><INDENT>def IsTopmost(self) -> bool:<DEDENT>

return bool(self.pattern.CurrentIsTopmost)<EOL>

Property IsTopmost.
Call IUIAutomationWindowPattern::get_CurrentIsTopmost.
Return bool, indicates whether the window is the topmost element in the z-order.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationwindowpattern-get_currentistopmost


@property<EOL><INDENT>def WindowInteractionState(self) -> int:<DEDENT>

return self.pattern.CurrentWindowInteractionState<EOL>

Property WindowInteractionState.
Call IUIAutomationWindowPattern::get_CurrentWindowInteractionState.
Return int, a value in class `WindowInteractionState`,
            the current state of the window for the purposes of user interaction.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationwindowpattern-get_currentwindowinteractionstate


@property<EOL><INDENT>def WindowVisualState(self) -> int:<DEDENT>

return self.pattern.CurrentWindowVisualState<EOL>

Property WindowVisualState.
Call IUIAutomationWindowPattern::get_CurrentWindowVisualState.
Return int, a value in class `WindowVisualState`,
            the visual state of the window; that is, whether it is in the normal, maximized, or minimized state.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationwindowpattern-get_currentwindowvisualstate


def SetWindowVisualState(self, state: int, waitTime: float = OPERATION_WAIT_TIME) -> bool:

ret = self.pattern.SetWindowVisualState(state) == S_OK<EOL>time.sleep(waitTime)<EOL>return ret<EOL>

Call IUIAutomationWindowPattern::SetWindowVisualState.
Minimize, maximize, or restore the window.
state: int, a value in class `WindowVisualState`.
waitTime: float.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationwindowpattern-setwindowvisualstate


def WaitForInputIdle(self, milliseconds: int) -> bool:

return self.pattern.WaitForInputIdle(milliseconds) == S_OK<EOL>

Call IUIAutomationWindowPattern::WaitForInputIdle.
Cause the calling code to block for the specified time or
    until the associated process enters an idle state, whichever completes first.
milliseconds: int.
Return bool, True if succeed otherwise False.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationwindowpattern-waitforinputidle


def __init__(self, searchFromControl: '<STR_LIT>' = None, searchDepth: int = <NUM_LIT>, searchWaitTime: float = SEARCH_INTERVAL, foundIndex: int = <NUM_LIT:1>, element=None, **searchProperties):

self._element = element<EOL>self._elementDirectAssign = True if element else False<EOL>self.searchFromControl = searchFromControl<EOL>self.searchDepth = searchProperties.get('<STR_LIT>', searchDepth)<EOL>self.searchWaitTime = searchWaitTime<EOL>self.foundIndex = foundIndex<EOL>self.searchProperties = searchProperties<EOL>regName = searchProperties.get('<STR_LIT>', '<STR_LIT>')<EOL>self.regexName = re.compile(regName) if regName else None<EOL>self._supportedPatterns = {}<EOL>

searchFromControl: `Control` or its subclass, if it is None, search from root control(Desktop).
searchDepth: int, max search depth from searchFromControl.
foundIndex: int, starts with 1, >= 1.
searchWaitTime: float, wait searchWaitTime before every search(interval between searchs).
element: `ctypes.POINTER(IUIAutomationElement)`, internal use.
searchProperties: defines how to search, the following keys can be used:
                    ControlType: int, a value in class `ControlType`.
                    ClassName: str.
                    AutomationId: str.
                    Name: str.
                    SubName: str, a part str in Name.
                    RegexName: str, supports regex using re.match.
                        You can only use one of Name, SubName, RegexName in searchProperties.
                    Depth: int, only search controls in relative depth from searchFromControl, ignore controls in depth(0~Depth-1),
                        if set, searchDepth will be set to Depth too.
                    Compare: Callable, custom compare function(control, depth)->bool.

`Control` wraps IUIAutomationElement.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nn-uiautomationclient-iuiautomationelement


@staticmethod<EOL><INDENT>def CreateControlFromElement(element) -> '<STR_LIT>':<DEDENT>

if element:<EOL><INDENT>controlType = element.CurrentControlType<EOL>if controlType in ControlConstructors:<EOL><INDENT>return ControlConstructors[controlType](element=element)<EOL><DEDENT>else:<EOL><INDENT>Logger.WriteLine("<STR_LIT>".format(controlType), ConsoleColor.Red)<EOL><DEDENT><DEDENT>

Create a concreate `Control` from a com type `IUIAutomationElement`.
element: `ctypes.POINTER(IUIAutomationElement)`.
Return a subclass of `Control`, an instance of the control's real type.


@staticmethod<EOL><INDENT>def CreateControlFromControl(control: '<STR_LIT>') -> '<STR_LIT>':<DEDENT>

newControl = Control.CreateControlFromElement(control.Element)<EOL>return newControl<EOL>

Create a concreate `Control` from a control instance, copy it.
control: `Control` or its subclass.
Return a subclass of `Control`, an instance of the control's real type.
For example: if control's ControlType is EditControl, return an EditControl.


def SetSearchFromControl(self, searchFromControl: '<STR_LIT>') -> None:

self.searchFromControl = searchFromControl<EOL>

searchFromControl: `Control` or its subclass


def AddSearchProperties(self, **searchProperties) -> None:

self.searchProperties.update(searchProperties)<EOL>if '<STR_LIT>' in searchProperties:<EOL><INDENT>self.searchDepth = searchProperties['<STR_LIT>']<EOL><DEDENT>if '<STR_LIT>' in searchProperties:<EOL><INDENT>regName = searchProperties['<STR_LIT>']<EOL>self.regexName = re.compile(regName) if regName else None<EOL><DEDENT>

Add search properties using `dict.update`.
searchProperties: dict, same as searchProperties in `Control.__init__`.


def RemoveSearchProperties(self, **searchProperties) -> None:

for key in searchProperties:<EOL><INDENT>del self.searchProperties[key]<EOL>if key == '<STR_LIT>':<EOL><INDENT>self.regexName = None<EOL><DEDENT><DEDENT>

searchProperties: dict, same as searchProperties in `Control.__init__`.


def GetColorfulSearchPropertiesStr(self, keyColor='<STR_LIT>', valueColor='<STR_LIT>') -> str:

strs = ['<STR_LIT>'.format(keyColor if k in Control.ValidKeys else '<STR_LIT>', k, valueColor,<EOL>ControlTypeNames[v] if k == '<STR_LIT>' else repr(v)) for k, v in self.searchProperties.items()]<EOL>return '<STR_LIT:{>' + '<STR_LIT:U+002CU+0020>'.join(strs) + '<STR_LIT:}>'<EOL>

keyColor, valueColor: str, color name in class ConsoleColor


@property<EOL><INDENT>def AcceleratorKey(self) -> str:<DEDENT>

return self.Element.CurrentAcceleratorKey<EOL>


@property<EOL><INDENT>def AccessKey(self) -> str:<DEDENT>

return self.Element.CurrentAccessKey<EOL>


@property<EOL><INDENT>def AriaProperties(self) -> str:<DEDENT>

return self.Element.CurrentAriaProperties<EOL>


@property<EOL><INDENT>def AriaRole(self) -> str:<DEDENT>

return self.Element.CurrentAriaRole<EOL>


@property<EOL><INDENT>def AutomationId(self) -> str:<DEDENT>

return self.Element.CurrentAutomationId<EOL>


@property<EOL><INDENT>def BoundingRectangle(self) -> Rect:<DEDENT>

rect = self.Element.CurrentBoundingRectangle<EOL>return Rect(rect.left, rect.top, rect.right, rect.bottom)<EOL>

Property BoundingRectangle.
Call IUIAutomationElement::get_CurrentBoundingRectangle.
Return `Rect`.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentboundingrectangle

rect = control.BoundingRectangle
print(rect.left, rect.top, rect.right, rect.bottom, rect.width(), rect.height(), rect.xcenter(), rect.ycenter())


@property<EOL><INDENT>def ClassName(self) -> str:<DEDENT>

return self.Element.CurrentClassName<EOL>


@property<EOL><INDENT>def ControlType(self) -> int:<DEDENT>

return self.Element.CurrentControlType<EOL>

Property ControlType.
Return int, a value in class `ControlType`.
Call IUIAutomationElement::get_CurrentControlType.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentcontroltype


@property<EOL><INDENT>def Culture(self) -> int:<DEDENT>

return self.Element.CurrentCulture<EOL>


@property<EOL><INDENT>def FrameworkId(self) -> str:<DEDENT>

return self.Element.CurrentFrameworkId<EOL>

Property FrameworkId.
Call IUIAutomationElement::get_CurrentFrameworkId.
Return str, such as Win32, WPF...
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentframeworkid


@property<EOL><INDENT>def HasKeyboardFocus(self) -> bool:<DEDENT>

return bool(self.Element.CurrentHasKeyboardFocus)<EOL>


@property<EOL><INDENT>def HelpText(self) -> str:<DEDENT>

return self.Element.CurrentHelpText<EOL>


@property<EOL><INDENT>def IsContentElement(self) -> bool:<DEDENT>

return bool(self.Element.CurrentIsContentElement)<EOL>


@property<EOL><INDENT>def IsControlElement(self) -> bool:<DEDENT>

return bool(self.Element.CurrentIsControlElement)<EOL>


@property<EOL><INDENT>def IsDataValidForForm(self) -> bool:<DEDENT>

return bool(self.Element.CurrentIsDataValidForForm)<EOL>


@property<EOL><INDENT>def IsEnabled(self) -> bool:<DEDENT>

return self.Element.CurrentIsEnabled<EOL>


@property<EOL><INDENT>def IsKeyboardFocusable(self) -> bool:<DEDENT>

return self.Element.CurrentIsKeyboardFocusable<EOL>


@property<EOL><INDENT>def IsOffscreen(self) -> bool:<DEDENT>

return self.Element.CurrentIsOffscreen<EOL>


@property<EOL><INDENT>def IsPassword(self) -> bool:<DEDENT>

return self.Element.CurrentIsPassword<EOL>


@property<EOL><INDENT>def IsRequiredForForm(self) -> bool:<DEDENT>

return self.Element.CurrentIsRequiredForForm<EOL>


@property<EOL><INDENT>def ItemStatus(self) -> str:<DEDENT>

return self.Element.CurrentItemStatus<EOL>


@property<EOL><INDENT>def ItemType(self) -> str:<DEDENT>

return self.Element.CurrentItemType<EOL>


@property<EOL><INDENT>def LocalizedControlType(self) -> str:<DEDENT>

return self.Element.CurrentLocalizedControlType<EOL>


@property<EOL><INDENT>def Name(self) -> str:<DEDENT>

return self.Element.CurrentName or '<STR_LIT>'<EOL>

Property Name.
Call IUIAutomationElement::get_CurrentName.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentname


@property<EOL><INDENT>def NativeWindowHandle(self) -> str:<DEDENT>

handle = self.Element.CurrentNativeWindowHandle<EOL>return <NUM_LIT:0> if handle is None else handle<EOL>


@property<EOL><INDENT>def Orientation(self) -> int:<DEDENT>

return self.Element.CurrentOrientation<EOL>

Property Orientation.
Return int, a value in class `OrientationType`.
Call IUIAutomationElement::get_CurrentOrientation.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentorientation


@property<EOL><INDENT>def ProcessId(self) -> int:<DEDENT>

return self.Element.CurrentProcessId<EOL>


@property<EOL><INDENT>def ProviderDescription(self) -> str:<DEDENT>

return self.Element.CurrentProviderDescription<EOL>


point, gotClickable = self.Element.GetClickablePoint()<EOL>return (point.x, point.y, bool(gotClickable))<EOL>

Call IUIAutomationElement::GetClickablePoint.
Return tuple, (x: int, y: int, gotClickable: bool), like (20, 10, True)
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getclickablepoint


try:<EOL><INDENT>pattern = self.Element.GetCurrentPattern(patternId)<EOL>if pattern:<EOL><INDENT>subPattern = CreatePattern(patternId, pattern)<EOL>self._supportedPatterns[patternId] = subPattern<EOL>return subPattern<EOL><DEDENT><DEDENT>except comtypes.COMError as ex:<EOL><INDENT>pass<EOL><DEDENT>

Call IUIAutomationElement::GetCurrentPattern.
Get a new pattern by pattern id if it supports the pattern.
patternId: int, a value in class `PatternId`.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcurrentpattern


def GetPatternAs(self, patternId: int, riid):

return self.Element.GetCurrentPatternAs(patternId, riid)<EOL>

Call IUIAutomationElement::GetCurrentPatternAs.
Get a new pattern by pattern id if it supports the pattern, todo.
patternId: int, a value in class `PatternId`.
riid: GUID.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcurrentpatternas


def GetPropertyValue(self, propertyId: int) -> Any:

return self.Element.GetCurrentPropertyValue(propertyId)<EOL>

Call IUIAutomationElement::GetCurrentPropertyValue.
propertyId: int, a value in class `PropertyId`.
Return Any, corresponding type according to propertyId.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcurrentpropertyvalue


def GetPropertyValueEx(self, propertyId: int, ignoreDefaultValue: int) -> Any:

return self.Element.GetCurrentPropertyValueEx(propertyId, ignoreDefaultValue)<EOL>

Call IUIAutomationElement::GetCurrentPropertyValueEx.
propertyId: int, a value in class `PropertyId`.
ignoreDefaultValue: int, 0 or 1.
Return Any, corresponding type according to propertyId.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcurrentpropertyvalueex


return self.Element.GetRuntimeId()<EOL>

Call IUIAutomationElement::GetRuntimeId.
Return list, a list of int.
Refer https://docs.microsoft.com/en-us/windows/desktop/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getruntimeid


return self.Element.SetFocus() == S_OK<EOL>


if not self._element:<EOL><INDENT>self.Refind(maxSearchSeconds=TIME_OUT_SECOND, searchIntervalSeconds=self.searchWaitTime)<EOL><DEDENT>return self._element<EOL>

Property Element.
Return `ctypes.POINTER(IUIAutomationElement)`.


@property<EOL><INDENT>def ControlTypeName(self) -> str:<DEDENT>

return ControlTypeNames[self.ControlType]<EOL>


def GetCachedPattern(self, patternId: int, cache: bool):

if cache:<EOL><INDENT>pattern = self._supportedPatterns.get(patternId, None)<EOL>if pattern:<EOL><INDENT>return pattern<EOL><DEDENT>else:<EOL><INDENT>pattern = self.GetPattern(patternId)<EOL>if pattern:<EOL><INDENT>self._supportedPatterns[patternId] = pattern<EOL>return pattern<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>pattern = self.GetPattern(patternId)<EOL>if pattern:<EOL><INDENT>self._supportedPatterns[patternId] = pattern<EOL>return pattern<EOL><DEDENT><DEDENT>

Get a pattern by patternId.
patternId: int, a value in class `PatternId`.
Return a pattern if it supports the pattern else None.
cache: bool, if True, store the pattern for later use, if False, get a new pattern by `self.GetPattern`.


def GetLegacyIAccessiblePattern(self) -> LegacyIAccessiblePattern:

return self.GetPattern(PatternId.LegacyIAccessiblePattern)<EOL>

Return `LegacyIAccessiblePattern` if it supports the pattern else None.


def GetAncestorControl(self, condition: Callable) -> '<STR_LIT>':

ancestor = self<EOL>depth = <NUM_LIT:0><EOL>while True:<EOL><INDENT>ancestor = ancestor.GetParentControl()<EOL>depth -= <NUM_LIT:1><EOL>if ancestor:<EOL><INDENT>if condition(ancestor, depth):<EOL><INDENT>return ancestor<EOL><DEDENT><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>

Get a ancestor control that matches the condition.
condition: Callable, function (control: Control, depth: int)->bool,
           depth starts with -1 and decreses when search goes up.
Return `Control` subclass or None.


def GetParentControl(self) -> '<STR_LIT>':

ele = _AutomationClient.instance().ViewWalker.GetParentElement(self.Element)<EOL>return Control.CreateControlFromElement(ele)<EOL>


def GetFirstChildControl(self) -> '<STR_LIT>':

ele = _AutomationClient.instance().ViewWalker.GetFirstChildElement(self.Element)<EOL>return Control.CreateControlFromElement(ele)<EOL>


def GetLastChildControl(self) -> '<STR_LIT>':

ele = _AutomationClient.instance().ViewWalker.GetLastChildElement(self.Element)<EOL>return Control.CreateControlFromElement(ele)<EOL>


def GetNextSiblingControl(self) -> '<STR_LIT>':

ele = _AutomationClient.instance().ViewWalker.GetNextSiblingElement(self.Element)<EOL>return Control.CreateControlFromElement(ele)<EOL>


def GetPreviousSiblingControl(self) -> '<STR_LIT>':

ele = _AutomationClient.instance().ViewWalker.GetPreviousSiblingElement(self.Element)<EOL>return Control.CreateControlFromElement(ele)<EOL>


def GetSiblingControl(self, condition: Callable, forward: bool = True) -> '<STR_LIT>':

if not forward:<EOL><INDENT>prev = self<EOL>while True:<EOL><INDENT>prev = prev.GetPreviousSiblingControl()<EOL>if prev:<EOL><INDENT>if condition(prev):<EOL><INDENT>return prev<EOL><DEDENT><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>next_ = self<EOL>while True:<EOL><INDENT>next_ = next_.GetNextSiblingControl()<EOL>if next_:<EOL><INDENT>if condition(next_):<EOL><INDENT>return next_<EOL><DEDENT><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>

Find a SiblingControl by condition(control: Control)->bool.
forward: bool, if True, only search next siblings, if False, search pervious siblings first, then search next siblings.
condition: Callable, function (control: Control)->bool.
Return `Control` subclass or None.


children = []<EOL>child = self.GetFirstChildControl()<EOL>while child:<EOL><INDENT>children.append(child)<EOL>child = child.GetNextSiblingControl()<EOL><DEDENT>return children<EOL>

Return list, a list of `Control` subclasses.


def _CompareFunction(self, control: '<STR_LIT>', depth: int) -> bool:

for key, value in self.searchProperties.items():<EOL><INDENT>if '<STR_LIT>' == key:<EOL><INDENT>if value != control.ControlType:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>elif '<STR_LIT>' == key:<EOL><INDENT>if value != control.ClassName:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>elif '<STR_LIT>' == key:<EOL><INDENT>if value != control.AutomationId:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>elif '<STR_LIT:Name>' == key:<EOL><INDENT>if value != control.Name:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>elif '<STR_LIT>' == key:<EOL><INDENT>if value not in control.Name:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>elif '<STR_LIT>' == key:<EOL><INDENT>if not self.regexName.match(control.Name):<EOL><INDENT>return False<EOL><DEDENT><DEDENT>elif '<STR_LIT>' == key:<EOL><INDENT>if value != depth:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>elif '<STR_LIT>' == key:<EOL><INDENT>if not value(control, depth):<EOL><INDENT>return False<EOL><DEDENT><DEDENT><DEDENT>return True<EOL>

Define how to search.
control: `Control` or its subclass.
depth: int, tree depth from searchFromControl.
Return bool.


def Exists(self, maxSearchSeconds: float = <NUM_LIT:5>, searchIntervalSeconds: float = SEARCH_INTERVAL, printIfNotExist: bool = False) -> bool:

if self._element and self._elementDirectAssign:<EOL><INDENT>rootElement = GetRootControl().Element<EOL>if self._element == rootElement:<EOL><INDENT>return True<EOL><DEDENT>else:<EOL><INDENT>parentElement = _AutomationClient.instance().ViewWalker.GetParentElement(self._element)<EOL>if parentElement:<EOL><INDENT>return True<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT><DEDENT><DEDENT>if len(self.searchProperties) == <NUM_LIT:0>:<EOL><INDENT>raise LookupError("<STR_LIT>")<EOL><DEDENT>self._element = None<EOL>startTime = ProcessTime()<EOL>prev =  self.searchFromControl<EOL>if prev and not prev._element and not prev.Exists(maxSearchSeconds, searchIntervalSeconds):<EOL><INDENT>if printIfNotExist or DEBUG_EXIST_DISAPPEAR:<EOL><INDENT>Logger.ColorfullyWriteLine(self.GetColorfulSearchPropertiesStr() + '<STR_LIT>')<EOL><DEDENT>return False<EOL><DEDENT>startTime2 = ProcessTime()<EOL>if DEBUG_SEARCH_TIME:<EOL><INDENT>startDateTime = datetime.datetime.now()<EOL><DEDENT>while True:<EOL><INDENT>control = FindControl(self.searchFromControl, self._CompareFunction, self.searchDepth, False, self.foundIndex)<EOL>if control:<EOL><INDENT>self._element = control.Element<EOL>control._element = <NUM_LIT:0>  <EOL>if DEBUG_SEARCH_TIME:<EOL><INDENT>Logger.ColorfullyWriteLine('<STR_LIT>'.format(<EOL>self.GetColorfulSearchPropertiesStr(), control.traverseCount, ProcessTime() - startTime2,<EOL>startDateTime.time(), datetime.datetime.now().time()))<EOL><DEDENT>return True<EOL><DEDENT>else:<EOL><INDENT>remain = startTime + maxSearchSeconds - ProcessTime()<EOL>if remain > <NUM_LIT:0>:<EOL><INDENT>time.sleep(min(remain, searchIntervalSeconds))<EOL><DEDENT>else:<EOL><INDENT>if printIfNotExist or DEBUG_EXIST_DISAPPEAR:<EOL><INDENT>Logger.ColorfullyWriteLine(self.GetColorfulSearchPropertiesStr() + '<STR_LIT>')<EOL><DEDENT>return False<EOL><DEDENT><DEDENT><DEDENT>

maxSearchSeconds: float
searchIntervalSeconds: float
Find control every searchIntervalSeconds seconds in maxSearchSeconds seconds.
Return bool, True if find


def Disappears(self, maxSearchSeconds: float = <NUM_LIT:5>, searchIntervalSeconds: float = SEARCH_INTERVAL, printIfNotDisappear: bool = False) -> bool:

global DEBUG_EXIST_DISAPPEAR<EOL>start = ProcessTime()<EOL>while True:<EOL><INDENT>temp = DEBUG_EXIST_DISAPPEAR<EOL>DEBUG_EXIST_DISAPPEAR = False  <EOL>if not self.Exists(<NUM_LIT:0>, <NUM_LIT:0>, False):<EOL><INDENT>DEBUG_EXIST_DISAPPEAR = temp<EOL>return True<EOL><DEDENT>DEBUG_EXIST_DISAPPEAR = temp<EOL>remain = start + maxSearchSeconds - ProcessTime()<EOL>if remain > <NUM_LIT:0>:<EOL><INDENT>time.sleep(min(remain, searchIntervalSeconds))<EOL><DEDENT>else:<EOL><INDENT>if printIfNotDisappear or DEBUG_EXIST_DISAPPEAR:<EOL><INDENT>Logger.ColorfullyWriteLine(self.GetColorfulSearchPropertiesStr() + '<STR_LIT>')<EOL><DEDENT>return False<EOL><DEDENT><DEDENT>

maxSearchSeconds: float
searchIntervalSeconds: float
Check if control disappears every searchIntervalSeconds seconds in maxSearchSeconds seconds.
Return bool, True if control disappears.


def Refind(self, maxSearchSeconds: float = TIME_OUT_SECOND, searchIntervalSeconds: float = SEARCH_INTERVAL, raiseException: bool = True) -> bool:

if not self.Exists(maxSearchSeconds, searchIntervalSeconds, False if raiseException else DEBUG_EXIST_DISAPPEAR):<EOL><INDENT>if raiseException:<EOL><INDENT>Logger.ColorfullyWriteLine('<STR_LIT>' + self.GetColorfulSearchPropertiesStr())<EOL>raise LookupError('<STR_LIT>' + self.GetSearchPropertiesStr())<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL>

Refind the control every searchIntervalSeconds seconds in maxSearchSeconds seconds.
maxSearchSeconds: float.
searchIntervalSeconds: float.
raiseException: bool, if True, raise a LookupError if timeout.
Return bool, True if find.


def MoveCursorToInnerPos(self, x: int = None, y: int = None, ratioX: float = <NUM_LIT:0.5>, ratioY: float = <NUM_LIT:0.5>, simulateMove: bool = True) -> tuple:

rect = self.BoundingRectangle<EOL>if rect.width() == <NUM_LIT:0> or rect.height() == <NUM_LIT:0>:<EOL><INDENT>Logger.ColorfullyWriteLine('<STR_LIT>'.format(<EOL>self.ControlTypeName, rect, self.GetColorfulSearchPropertiesStr()))<EOL>return<EOL><DEDENT>if x is None:<EOL><INDENT>x = rect.left + int(rect.width() * ratioX)<EOL><DEDENT>else:<EOL><INDENT>x = (rect.left if x >= <NUM_LIT:0> else rect.right) + x<EOL><DEDENT>if y is None:<EOL><INDENT>y = rect.top + int(rect.height() * ratioY)<EOL><DEDENT>else:<EOL><INDENT>y = (rect.top if y >= <NUM_LIT:0> else rect.bottom) + y<EOL><DEDENT>if simulateMove and MAX_MOVE_SECOND > <NUM_LIT:0>:<EOL><INDENT>MoveTo(x, y, waitTime=<NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>SetCursorPos(x, y)<EOL><DEDENT>return x, y<EOL>

Move cursor to control's internal position, default to center.
x: int, if < 0, move to self.BoundingRectangle.right + x, if not None, ignore ratioX.
y: int, if < 0, move to self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
ratioX: float.
ratioY: float.
simulateMove: bool.
Return tuple, two ints(x,y), the cursor positon relative to screen(0,0) after moving or None if control's width or height == 0.


def MoveCursorToMyCenter(self, simulateMove: bool = True) -> tuple:

return self.MoveCursorToInnerPos(simulateMove=simulateMove)<EOL>

Move cursor to control's center.
Return tuple, two ints tuple(x,y), the cursor positon relative to screen(0,0) after moving .


def Click(self, x: int = None, y: int = None, ratioX: float = <NUM_LIT:0.5>, ratioY: float = <NUM_LIT:0.5>, simulateMove: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> None:

point = self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove)<EOL>if point:<EOL><INDENT>Click(point[<NUM_LIT:0>], point[<NUM_LIT:1>], waitTime)<EOL><DEDENT>

x: int, if < 0, click self.BoundingRectangle.right + x, if not None, ignore ratioX.
y: int, if < 0, click self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
ratioX: float.
ratioY: float.
simulateMove: bool, if True, first move cursor to control smoothly.
waitTime: float.

Click(), Click(ratioX=0.5, ratioY=0.5): click center.
Click(10, 10): click left+10, top+10.
Click(-10, -10): click right-10, bottom-10.


def MiddleClick(self, x: int = None, y: int = None, ratioX: float = <NUM_LIT:0.5>, ratioY: float = <NUM_LIT:0.5>, simulateMove: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> None:

point = self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove)<EOL>if point:<EOL><INDENT>MiddleClick(point[<NUM_LIT:0>], point[<NUM_LIT:1>], waitTime)<EOL><DEDENT>

x: int, if < 0, middle click self.BoundingRectangle.right + x, if not None, ignore ratioX.
y: int, if < 0, middle click self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
ratioX: float.
ratioY: float.
simulateMove: bool, if True, first move cursor to control smoothly.
waitTime: float.

MiddleClick(), MiddleClick(ratioX=0.5, ratioY=0.5): middle click center.
MiddleClick(10, 10): middle click left+10, top+10.
MiddleClick(-10, -10): middle click right-10, bottom-10.


def RightClick(self, x: int = None, y: int = None, ratioX: float = <NUM_LIT:0.5>, ratioY: float = <NUM_LIT:0.5>, simulateMove: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> None:

point = self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove)<EOL>if point:<EOL><INDENT>RightClick(point[<NUM_LIT:0>], point[<NUM_LIT:1>], waitTime)<EOL><DEDENT>

x: int, if < 0, right click self.BoundingRectangle.right + x, if not None, ignore ratioX.
y: int, if < 0, right click self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
ratioX: float.
ratioY: float.
simulateMove: bool, if True, first move cursor to control smoothly.
waitTime: float.

RightClick(), RightClick(ratioX=0.5, ratioY=0.5): right click center.
RightClick(10, 10): right click left+10, top+10.
RightClick(-10, -10): right click right-10, bottom-10.


def DoubleClick(self, x: int = None, y: int = None, ratioX: float = <NUM_LIT:0.5>, ratioY: float = <NUM_LIT:0.5>, simulateMove: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> None:

x, y = self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove)<EOL>Click(x, y, GetDoubleClickTime() * <NUM_LIT:1.0> / <NUM_LIT>)<EOL>Click(x, y, waitTime)<EOL>

x: int, if < 0, right click self.BoundingRectangle.right + x, if not None, ignore ratioX.
y: int, if < 0, right click self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
ratioX: float.
ratioY: float.
simulateMove: bool, if True, first move cursor to control smoothly.
waitTime: float.

DoubleClick(), DoubleClick(ratioX=0.5, ratioY=0.5): double click center.
DoubleClick(10, 10): double click left+10, top+10.
DoubleClick(-10, -10): double click right-10, bottom-10.


def WheelDown(self, wheelTimes: int = <NUM_LIT:1>, interval: float = <NUM_LIT>, waitTime: float = OPERATION_WAIT_TIME) -> None:

x, y = GetCursorPos()<EOL>self.SetFocus()<EOL>self.MoveCursorToMyCenter(False)<EOL>WheelDown(wheelTimes, interval, waitTime)<EOL>SetCursorPos(x, y)<EOL>

Make control have focus first, move cursor to center and mouse wheel down.
wheelTimes: int.
interval: float.
waitTime: float.


def WheelUp(self, wheelTimes: int = <NUM_LIT:1>, interval: float = <NUM_LIT>, waitTime: float = OPERATION_WAIT_TIME) -> None:

x, y = GetCursorPos()<EOL>self.SetFocus()<EOL>self.MoveCursorToMyCenter(False)<EOL>WheelUp(wheelTimes, interval, waitTime)<EOL>SetCursorPos(x, y)<EOL>

Make control have focus first, move cursor to center and mouse wheel up.
wheelTimes: int.
interval: float.
waitTime: float.


def ShowWindow(self, cmdShow: int, waitTime: float = OPERATION_WAIT_TIME) -> bool:

handle = self.NativeWindowHandle<EOL>if not handle:<EOL><INDENT>control = self<EOL>while not handle:<EOL><INDENT>control = control.GetParentControl()<EOL>handle = control.NativeWindowHandle<EOL><DEDENT><DEDENT>if handle:<EOL><INDENT>ret = ShowWindow(handle, cmdShow)<EOL>time.sleep(waitTime)<EOL>return ret<EOL><DEDENT>

Get a native handle from self or ancestors until valid and call native `ShowWindow` with cmdShow.
cmdShow: int, a value in in class `SW`.
waitTime: float.
Return bool, True if succeed otherwise False.


def Show(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

return self.ShowWindow(SW.Show, waitTime)<EOL>

Call native `ShowWindow(SW.Show)`.
Return bool, True if succeed otherwise False.


def Hide(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

return self.ShowWindow(SW.Hide, waitTime)<EOL>

Call native `ShowWindow(SW.Hide)`.
waitTime: float
Return bool, True if succeed otherwise False.


def MoveWindow(self, x: int, y: int, width: int, height: int, repaint: bool = True) -> bool:

handle = self.NativeWindowHandle<EOL>if handle:<EOL><INDENT>return MoveWindow(handle, x, y, width, height, int(repaint))<EOL><DEDENT>return False<EOL>

Call native MoveWindow if control has a valid native handle.
x: int.
y: int.
width: int.
height: int.
repaint: bool.
Return bool, True if succeed otherwise False.


handle = self.NativeWindowHandle<EOL>if handle:<EOL><INDENT>return GetWindowText(handle)<EOL><DEDENT>

Call native GetWindowText if control has a valid native handle.


def SetWindowText(self, text: str) -> bool:

handle = self.NativeWindowHandle<EOL>if handle:<EOL><INDENT>return SetWindowText(handle, text)<EOL><DEDENT>return False<EOL>

Call native SetWindowText if control has a valid native handle.


def SendKey(self, key: int, waitTime: float = OPERATION_WAIT_TIME) -> None:

self.SetFocus()<EOL>SendKey(key, waitTime)<EOL>

Make control have focus first and type a key.
`self.SetFocus` may not work for some controls, you may need to click it to make it have focus.
key: int, a key code value in class Keys.
waitTime: float.


def SendKeys(self, keys: str, interval: float = <NUM_LIT>, waitTime: float = OPERATION_WAIT_TIME) -> None:

self.SetFocus()<EOL>SendKeys(keys, interval, waitTime)<EOL>

Make control have focus first and type keys.
`self.SetFocus` may not work for some controls, you may need to click it to make it have focus.
keys: str, keys to type, see the docstring of `SendKeys`.
interval: float, seconds between keys.


def GetPixelColor(self, x: int, y: int) -> int:

handle = self.NativeWindowHandle<EOL>if handle:<EOL><INDENT>return GetPixelColor(x, y, handle)<EOL><DEDENT>

Call native `GetPixelColor` if control has a valid native handle.
Use `self.ToBitmap` if control doesn't have a valid native handle or you get many pixels.
x: int, internal x position.
y: int, internal y position.
Return int, a color value in bgr.
r = bgr & 0x0000FF
g = (bgr & 0x00FF00) >> 8
b = (bgr & 0xFF0000) >> 16


def ToBitmap(self, x: int = <NUM_LIT:0>, y: int = <NUM_LIT:0>, width: int = <NUM_LIT:0>, height: int = <NUM_LIT:0>) -> Bitmap:

bitmap = Bitmap()<EOL>bitmap.FromControl(self, x, y, width, height)<EOL>return bitmap<EOL>

Capture control to a Bitmap object.
x, y: int, the point in control's internal position(from 0,0).
width, height: int, image's width and height from x, y, use 0 for entire area.
               If width(or height) < 0, image size will be control's width(or height) - width(or height).


def CaptureToImage(self, savePath: str, x: int = <NUM_LIT:0>, y: int = <NUM_LIT:0>, width: int = <NUM_LIT:0>, height: int = <NUM_LIT:0>) -> bool:

bitmap = Bitmap()<EOL>if bitmap.FromControl(self, x, y, width, height):<EOL><INDENT>return bitmap.ToFile(savePath)<EOL><DEDENT>return False<EOL>

Capture control to a image file.
savePath: str, should end with .bmp, .jpg, .jpeg, .png, .gif, .tif, .tiff.
x, y: int, the point in control's internal position(from 0,0).
width, height: int, image's width and height from x, y, use 0 for entire area.
               If width(or height) < 0, image size will be control's width(or height) - width(or height).
Return bool, True if succeed otherwise False.


handle = self.NativeWindowHandle<EOL>if handle:<EOL><INDENT>return GetAncestor(handle, GAFlag.Root) == handle<EOL><DEDENT>return False<EOL>

Determine whether current control is top level.


def GetTopLevelControl(self) -> '<STR_LIT>':

handle = self.NativeWindowHandle<EOL>if handle:<EOL><INDENT>topHandle = GetAncestor(handle, GAFlag.Root)<EOL>if topHandle:<EOL><INDENT>if topHandle == handle:<EOL><INDENT>return self<EOL><DEDENT>else:<EOL><INDENT>return ControlFromHandle(topHandle)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>else:<EOL><INDENT>control = self<EOL>while True:<EOL><INDENT>control = control.GetParentControl()<EOL>handle = control.NativeWindowHandle<EOL>if handle:<EOL><INDENT>topHandle = GetAncestor(handle, GAFlag.Root)<EOL>return ControlFromHandle(topHandle)<EOL><DEDENT><DEDENT><DEDENT>

Get the top level control which current control lays.
If current control is top level, return self.
If current control is root control, return None.
Return `PaneControl` or `WindowControl` or None.


def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:

return self.GetPattern(PatternId.ExpandCollapsePattern)<EOL>

Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetInvokePattern(self) -> InvokePattern:

return self.GetPattern(PatternId.InvokePattern)<EOL>

Return `InvokePattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetTogglePattern(self) -> TogglePattern:

return self.GetPattern(PatternId.TogglePattern)<EOL>

Return `TogglePattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetGridPattern(self) -> GridPattern:

return self.GetPattern(PatternId.GridPattern)<EOL>

Return `GridPattern` if it supports the pattern else None(Must support according to MSDN).


def GetTablePattern(self) -> TablePattern:

return self.GetPattern(PatternId.TablePattern)<EOL>

Return `TablePattern` if it supports the pattern else None(Must support according to MSDN).


def GetScrollPattern(self) -> ScrollPattern:

return self.GetPattern(PatternId.ScrollPattern)<EOL>

Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetSelectionPattern(self) -> SelectionPattern:

return self.GetPattern(PatternId.SelectionPattern)<EOL>

Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `TogglePattern` if it supports the pattern else None(Must support according to MSDN).


Return `ExpandCollapsePattern` if it supports the pattern else None(Must support according to MSDN).


def GetValuePattern(self) -> ValuePattern:

return self.GetPattern(PatternId.ValuePattern)<EOL>

Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).


def Select(self, itemName: str = '<STR_LIT>', condition: Callable = None, waitTime: float = OPERATION_WAIT_TIME) -> bool:

expandCollapsePattern = self.GetExpandCollapsePattern()<EOL>if expandCollapsePattern:<EOL><INDENT>expandCollapsePattern.Expand()<EOL><DEDENT>else:<EOL><INDENT>self.Click(x=-<NUM_LIT:10>, ratioY=<NUM_LIT:0.5>, simulateMove=False)<EOL><DEDENT>find = False<EOL>if condition:<EOL><INDENT>listItemControl = self.ListItemControl(Compare=lambda c, d: condition(c.Name))<EOL><DEDENT>else:<EOL><INDENT>listItemControl = self.ListItemControl(Name=itemName)<EOL><DEDENT>if listItemControl.Exists(<NUM_LIT:1>):<EOL><INDENT>scrollItemPattern = listItemControl.GetScrollItemPattern()<EOL>if scrollItemPattern:<EOL><INDENT>scrollItemPattern.ScrollIntoView(waitTime=<NUM_LIT:0.1>)<EOL><DEDENT>listItemControl.Click(waitTime=waitTime)<EOL>find = True<EOL><DEDENT>else:<EOL><INDENT>listControl = ListControl(searchDepth= <NUM_LIT:1>)<EOL>if listControl.Exists(<NUM_LIT:1>):<EOL><INDENT>if condition:<EOL><INDENT>listItemControl = self.ListItemControl(Compare=lambda c, d: condition(c.Name))<EOL><DEDENT>else:<EOL><INDENT>listItemControl = self.ListItemControl(Name=itemName)<EOL><DEDENT>if listItemControl.Exists(<NUM_LIT:0>, <NUM_LIT:0>):<EOL><INDENT>scrollItemPattern = listItemControl.GetScrollItemPattern()<EOL>if scrollItemPattern:<EOL><INDENT>scrollItemPattern.ScrollIntoView(waitTime=<NUM_LIT:0.1>)<EOL><DEDENT>listItemControl.Click(waitTime=waitTime)<EOL>find = True<EOL><DEDENT><DEDENT><DEDENT>if not find:<EOL><INDENT>Logger.ColorfullyWriteLine('<STR_LIT>'.format(itemName), ConsoleColor.Yellow)<EOL>if expandCollapsePattern:<EOL><INDENT>expandCollapsePattern.Collapse(waitTime)<EOL><DEDENT>else:<EOL><INDENT>self.Click(x=-<NUM_LIT:10>, ratioY=<NUM_LIT:0.5>, simulateMove=False, waitTime=waitTime)<EOL><DEDENT><DEDENT>return find<EOL>

Show combobox's popup menu and select a item by name.
itemName: str.
condition: Callable function(comboBoxItemName: str)->bool, if condition is valid, ignore itemName.
waitTime: float.
Some comboboxs doesn't support SelectionPattern, here is a workaround.
This method tries to and selection support.
It may not work for some comboboxes, such as comboboxes in older Qt version.
If it doesn't work, you should write your own version Select, or it doesn't support selection at all.


Return `TablePattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetSelectionItemPattern(self) -> SelectionItemPattern:

return self.GetPattern(PatternId.SelectionItemPattern)<EOL>

Return `SelectionItemPattern` if it supports the pattern else None(Must support according to MSDN).


def GetGridItemPattern(self) -> GridItemPattern:

return self.GetPattern(PatternId.GridItemPattern)<EOL>

Return `GridItemPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetScrollItemPattern(self) -> ScrollItemPattern:

return self.GetPattern(PatternId.ScrollItemPattern)<EOL>

Return `ScrollItemPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetTableItemPattern(self) -> TableItemPattern:

return self.GetPattern(PatternId.TableItemPattern)<EOL>

Return `TableItemPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetTextPattern(self) -> TextPattern:

return self.GetPattern(PatternId.TextPattern)<EOL>

Return `TextPattern` if it supports the pattern else None(Must support according to MSDN).


def GetRangeValuePattern(self) -> RangeValuePattern:

return self.GetPattern(PatternId.RangeValuePattern)<EOL>

Return `RangeValuePattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `TextPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetTransformPattern(self) -> TransformPattern:

return self.GetPattern(PatternId.TransformPattern)<EOL>

Return `TransformPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `InvokePattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `InvokePattern` if it supports the pattern else None(Must support according to MSDN).


Return `GridPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetMultipleViewPattern(self) -> MultipleViewPattern:

return self.GetPattern(PatternId.MultipleViewPattern)<EOL>

Return `MultipleViewPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `SelectionPattern` if it supports the pattern else None(Must support according to MSDN).


def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:

return self.GetPattern(PatternId.ExpandCollapsePattern)<EOL>


def GetInvokePattern(self) -> InvokePattern:

return self.GetPattern(PatternId.InvokePattern)<EOL>


def GetTogglePattern(self) -> TogglePattern:

return self.GetPattern(PatternId.TogglePattern)<EOL>

Return `TogglePattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetDockPattern(self) -> DockPattern:

return self.GetPattern(PatternId.DockPattern)<EOL>

Return `DockPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `SelectionItemPattern` if it supports the pattern else None(Conditional support according to MSDN).


def SetTopmost(self, isTopmost: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> bool:

if self.IsTopLevel():<EOL><INDENT>ret = SetWindowTopmost(self.NativeWindowHandle, isTopmost)<EOL>time.sleep(waitTime)<EOL>return ret<EOL><DEDENT>return False<EOL>

Set top level window topmost.
isTopmost: bool.
waitTime: float.


def Maximize(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

if self.IsTopLevel():<EOL><INDENT>return self.ShowWindow(SW.ShowMaximized, waitTime)<EOL><DEDENT>return False<EOL>


def Restore(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

if self.IsTopLevel():<EOL><INDENT>return self.ShowWindow(SW.Restore, waitTime)<EOL><DEDENT>return False<EOL>

Restore window to normal state.
Similar to SwitchToThisWindow.


if self.IsTopLevel():<EOL><INDENT>rect = self.BoundingRectangle<EOL>screenWidth, screenHeight = GetScreenSize()<EOL>x, y = (screenWidth - rect.width()) // <NUM_LIT:2>, (screenHeight - rect.height()) // <NUM_LIT:2><EOL>if x < <NUM_LIT:0>: x = <NUM_LIT:0><EOL>if y < <NUM_LIT:0>: y = <NUM_LIT:0><EOL>return SetWindowPos(self.NativeWindowHandle, SWP.HWND_Top, x, y, <NUM_LIT:0>, <NUM_LIT:0>, SWP.SWP_NoSize)<EOL><DEDENT>return False<EOL>


def SetActive(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:

if self.IsTopLevel():<EOL><INDENT>handle = self.NativeWindowHandle<EOL>if IsIconic(handle):<EOL><INDENT>ret = ShowWindow(handle, SW.Restore)<EOL><DEDENT>elif not IsWindowVisible(handle):<EOL><INDENT>ret = ShowWindow(handle, SW.Show)<EOL><DEDENT>ret = SetForegroundWindow(handle)  <EOL>time.sleep(waitTime)<EOL>return ret<EOL><DEDENT>return False<EOL>


def GetScrollPattern(self) -> ScrollPattern:

return self.GetPattern(PatternId.ScrollPattern)<EOL>


Return `RangeValuePattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetValuePattern(self) -> ValuePattern:

return self.GetPattern(PatternId.ValuePattern)<EOL>


def GetSelectionItemPattern(self) -> SelectionItemPattern:

return self.GetPattern(PatternId.SelectionItemPattern)<EOL>

Return `SelectionItemPattern` if it supports the pattern else None(Must support according to MSDN).


def GetSelectionPattern(self) -> SelectionPattern:

return self.GetPattern(PatternId.SelectionPattern)<EOL>


Return `ExpandCollapsePattern` if it supports the pattern else None(Must support according to MSDN).


def GetGridPattern(self) -> GridPattern:

return self.GetPattern(PatternId.GridPattern)<EOL>


Return `GridPattern` if it supports the pattern else None(Must support according to MSDN).


def GetGridItemPattern(self) -> GridItemPattern:

return self.GetPattern(PatternId.GridItemPattern)<EOL>

Return `GridItemPattern` if it supports the pattern else None(Must support according to MSDN).


def GetTablePattern(self) -> TablePattern:

return self.GetPattern(PatternId.TablePattern)<EOL>

Return `TablePattern` if it supports the pattern else None(Must support according to MSDN).


def GetTableItemPattern(self) -> TableItemPattern:

return self.GetPattern(PatternId.TableItemPattern)<EOL>

Return `TableItemPattern` if it supports the pattern else None(Must support according to MSDN).


Return `GridItemPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `TableItemPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetTextPattern(self) -> TextPattern:

return self.GetPattern(PatternId.TextPattern)<EOL>

Return `TextPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetTransformPattern(self) -> TransformPattern:

return self.GetPattern(PatternId.TransformPattern)<EOL>

Return `TransformPattern` if it supports the pattern else None(Must support according to MSDN).


def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:

return self.GetPattern(PatternId.ExpandCollapsePattern)<EOL>

Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `TransformPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetWindowPattern(self) -> WindowPattern:

return self.GetPattern(PatternId.WindowPattern)<EOL>

Return `WindowPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetInvokePattern(self) -> InvokePattern:

return self.GetPattern(PatternId.InvokePattern)<EOL>

Return `InvokePattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetScrollItemPattern(self) -> ScrollItemPattern:

return self.GetPattern(PatternId.ScrollItemPattern)<EOL>

Return `ScrollItemPattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `SelectionItemPattern` if it supports the pattern else None(Conditional support according to MSDN).


def GetTogglePattern(self) -> TogglePattern:

return self.GetPattern(PatternId.TogglePattern)<EOL>

Return `TogglePattern` if it supports the pattern else None(Conditional support according to MSDN).


Return `WindowPattern` if it supports the pattern else None(Must support according to MSDN).


def GetDockPattern(self) -> DockPattern:

return self.GetPattern(PatternId.DockPattern)<EOL>

Return `DockPattern` if it supports the pattern else None(Conditional support according to MSDN).


def MetroClose(self, waitTime: float = OPERATION_WAIT_TIME) -> None:

if self.ClassName == METRO_WINDOW_CLASS_NAME:<EOL><INDENT>screenWidth, screenHeight = GetScreenSize()<EOL>MoveTo(screenWidth // <NUM_LIT:2>, <NUM_LIT:0>, waitTime=<NUM_LIT:0>)<EOL>DragDrop(screenWidth // <NUM_LIT:2>, <NUM_LIT:0>, screenWidth // <NUM_LIT:2>, screenHeight, waitTime=waitTime)<EOL><DEDENT>else:<EOL><INDENT>Logger.WriteLine('<STR_LIT>', ConsoleColor.Yellow)<EOL><DEDENT>

Only work on Windows 8/8.1, if current window is Metro UI.
waitTime: float.


data = record._raw.copy()<EOL>data['<STR_LIT:time>'] = data['<STR_LIT:time>'].isoformat()<EOL>if data.get('<STR_LIT>'):<EOL><INDENT>data['<STR_LIT>'] = self.formatException(data['<STR_LIT>'])<EOL><DEDENT>return json.dumps(data)<EOL>

JSON-encode a record for serializing through redis.

Convert date to iso format, and stringify any exceptions.


def __init__(self, channel, redis_client, level=logging.NOTSET):

logging.Handler.__init__(self, level)<EOL>self.channel = channel<EOL>self.redis_client = redis_client<EOL>self.formatter = RedisFormatter()<EOL>

Create a new logger for the given channel and redis_client.


try:<EOL><INDENT>self.redis_client.publish(self.channel, self.format(record))<EOL><DEDENT>except redis.RedisError:<EOL><INDENT>pass<EOL><DEDENT>


def __init__(self, key, max_messages, redis_client, level=logging.NOTSET):

logging.Handler.__init__(self, level)<EOL>self.key = key<EOL>self.redis_client = redis_client<EOL>self.formatter = RedisFormatter()<EOL>self.max_messages = max_messages<EOL>

Create a new logger for the given key and redis_client.


try:<EOL><INDENT>if self.max_messages:<EOL><INDENT>p = self.redis_client.pipeline()<EOL>p.rpush(self.key, self.format(record))<EOL>p.ltrim(self.key, -self.max_messages, -<NUM_LIT:1>)<EOL>p.execute()<EOL><DEDENT>else:<EOL><INDENT>self.redis_client.rpush(self.key, self.format(record))<EOL><DEDENT><DEDENT>except redis.RedisError:<EOL><INDENT>pass<EOL><DEDENT>


frames = inspect.stack()<EOL>if len(frames) > <NUM_LIT:4>:<EOL><INDENT>context = frames[<NUM_LIT:5>]<EOL><DEDENT>else:<EOL><INDENT>context = frames[<NUM_LIT:0>]<EOL><DEDENT>modname = context[<NUM_LIT:1>]<EOL>lineno = context[<NUM_LIT:2>]<EOL>if context[<NUM_LIT:3>]:<EOL><INDENT>funcname = context[<NUM_LIT:3>]<EOL><DEDENT>else:<EOL><INDENT>funcname = "<STR_LIT>"<EOL><DEDENT>del context<EOL>del frames<EOL>return modname, funcname, lineno<EOL>

Utility function for the RedisLogRecord.

Returns the module, function, and lineno of the function
that called the logger.

We look way up in the stack.  The stack at this point is:
[0] logger.py _getCallingContext (hey, that's me!)
[1] logger.py __init__
[2] logger.py makeRecord
[3] _log
[4] <logging method>
[5] caller of logging method


def autocomplete(query, country=None, hurricanes=False, cities=True, timeout=<NUM_LIT:5>):

data = {}<EOL>data['<STR_LIT>'] = quote(query)<EOL>data['<STR_LIT>'] = country or '<STR_LIT>'<EOL>data['<STR_LIT>'] = <NUM_LIT:1> if hurricanes else <NUM_LIT:0><EOL>data['<STR_LIT>'] = <NUM_LIT:1> if cities else <NUM_LIT:0><EOL>data['<STR_LIT>'] = '<STR_LIT>'<EOL>r = requests.get(AUTOCOMPLETE_URL.format(**data), timeout=timeout)<EOL>results = json.loads(r.content)['<STR_LIT>']<EOL>return results<EOL>

Make an autocomplete API request

    This can be used to find cities and/or hurricanes by name

    :param string query: city
    :param string country: restrict search to a specific country. Must be a two letter country code
    :param boolean hurricanes: whether to search for hurricanes or not
    :param boolean cities: whether to search for cities or not
    :param integer timeout: timeout of the api request
    :returns: result of the autocomplete API request
    :rtype: dict


def request(key, features, query, timeout=<NUM_LIT:5>):

data = {}<EOL>data['<STR_LIT:key>'] = key<EOL>data['<STR_LIT>'] = '<STR_LIT:/>'.join([f for f in features if f in FEATURES])<EOL>data['<STR_LIT>'] = quote(query)<EOL>data['<STR_LIT>'] = '<STR_LIT>'<EOL>r = requests.get(API_URL.format(**data), timeout=timeout)<EOL>results = json.loads(_unicode(r.content))<EOL>return results<EOL>

Make an API request

    :param string key: API key to use
    :param list features: features to request. It must be a subset of :data:`FEATURES`
    :param string query: query to send
    :param integer timeout: timeout of the request
    :returns: result of the API request
    :rtype: dict


for encoding in ['<STR_LIT:utf-8>', '<STR_LIT>']:<EOL><INDENT>try:<EOL><INDENT>result = unicode(string, encoding)<EOL>return result<EOL><DEDENT>except UnicodeDecodeError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>result = unicode(string, '<STR_LIT:utf-8>', '<STR_LIT:replace>')<EOL>return result<EOL>

Try to convert a string to unicode using different encodings


def __init__(self, req, required=False):

self.requirement = req<EOL>self.required = required<EOL>self.required_by = None<EOL>

:param pkg_resources.Requirement req:
:param bool required: Is this requirement required to be fulfilled? If not, then it is a filter.


@classmethod<EOL><INDENT>def parse(cls, s, required=False):<DEDENT>

req = pkg_resources.Requirement.parse(s)<EOL>return cls(req, required=required)<EOL>

Parse string to create an instance

:param str s: String with requirement to parse
:param bool required: Is this requirement required to be fulfilled? If not, then it is a filter.


self.requirements = defaultdict(list)<EOL>self.matched_name = False<EOL>self.checked = []<EOL>if requirements:<EOL><INDENT>self.add(requirements)<EOL><DEDENT>

:param list requirements: List of requirements to manage


def add(self, requirements, required=None):

if isinstance(requirements, RequirementsManager):<EOL><INDENT>requirements = list(requirements)<EOL><DEDENT>elif not isinstance(requirements, list):<EOL><INDENT>requirements = [requirements]<EOL><DEDENT>for req in requirements:<EOL><INDENT>name = req.project_name<EOL>if not isinstance(req, BumpRequirement):<EOL><INDENT>req = BumpRequirement(req, required=required)<EOL><DEDENT>elif required is not None:<EOL><INDENT>req.required = required<EOL><DEDENT>add = True<EOL>if name in self.requirements:<EOL><INDENT>for existing_req in self.requirements[name]:<EOL><INDENT>if req == existing_req:<EOL><INDENT>add = False<EOL>break<EOL><DEDENT>replace = False<EOL>if (req.specs and req.specs[<NUM_LIT:0>][<NUM_LIT:0>] == '<STR_LIT>' and existing_req.specs and<EOL>existing_req.specs[<NUM_LIT:0>][<NUM_LIT:0>] == '<STR_LIT>'):<EOL><INDENT>if pkg_resources.parse_version(req.specs[<NUM_LIT:0>][<NUM_LIT:1>]) < pkg_resources.parse_version(<EOL>existing_req.specs[<NUM_LIT:0>][<NUM_LIT:1>]):<EOL><INDENT>req.requirement = existing_req.requirement<EOL><DEDENT>replace = True<EOL><DEDENT>if not (req.specs and existing_req.specs):<EOL><INDENT>if existing_req.specs:<EOL><INDENT>req.requirement = existing_req.requirement<EOL><DEDENT>replace = True<EOL><DEDENT>if replace:<EOL><INDENT>req.required |= existing_req.required<EOL>if existing_req.required_by and not req.required_by:<EOL><INDENT>req.required_by = existing_req.required_by<EOL><DEDENT>self.requirements[name].remove(existing_req)<EOL>break<EOL><DEDENT><DEDENT><DEDENT>if add:<EOL><INDENT>self.requirements[name].append(req)<EOL><DEDENT><DEDENT>

Add requirements to be managed

:param list/Requirement requirements: List of :class:`BumpRequirement` or :class:`pkg_resources.Requirement`
:param bool required: Set required flag for each requirement if provided.


req_str = None<EOL>self.checked.append((context, version))<EOL>if isinstance(context, str) and not version:<EOL><INDENT>context = BumpRequirement.parse(context)<EOL><DEDENT>if isinstance(context, Bump):<EOL><INDENT>name = context.name<EOL>if context.new_version and context.new_version[<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>version = context.new_version[<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>req_str = str(context)<EOL><DEDENT><DEDENT>elif isinstance(context, (pkg_resources.Requirement, BumpRequirement)):<EOL><INDENT>name = context.project_name<EOL>if context.specs and context.specs[<NUM_LIT:0>][<NUM_LIT:0>] == '<STR_LIT>':<EOL><INDENT>version = context.specs[<NUM_LIT:0>][<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>req_str = str(context)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>name = context<EOL><DEDENT>if name in self:<EOL><INDENT>self.matched_name = True<EOL>for req in self[name]:<EOL><INDENT>if req.required and (version and version in req or req_str == str(req)):<EOL><INDENT>req.required = False<EOL>return True<EOL><DEDENT><DEDENT><DEDENT>return False<EOL>

Check off requirements that are met by name/version.

:param str|Bump|Requirement context: Either package name, requirement string, :class:`Bump`,
                                     :class:`BumpRequirement`, or
                                     :class:`pkg_resources.Requirement instance
:return: True if any requirement was satisified by context


req_man = RequirementsManager([req])<EOL>return any(req_man.check(*checked) for checked in self.checked)<EOL>

Check if requirement is already satisfied by what was previously checked

:param Requirement req: Requirement to check


def __init__(self, name, new_version=None, changes=None, requirements=None):

self.name = name<EOL>self.new_version = new_version<EOL>self.changes = changes or []<EOL>self.requirements = []<EOL>if requirements:<EOL><INDENT>self.require(requirements)<EOL><DEDENT>

:param str name: Name of the product/library that was bumped
:param tuple new_version: New version that was bumped to in (op, version) format.
:param list changes: Detailed changelog entries from the old version to the new version
:param str|list requirements: Any requirements that must be fulfilled for this bump to occur.


@classmethod<EOL><INDENT>def from_requirement(cls, req, changes=None):<DEDENT>

return cls(req.project_name, req.specs and '<STR_LIT>'.join(req.specs[<NUM_LIT:0>]) or '<STR_LIT>', changes=changes)<EOL>

Create an instance from :class:`pkg_resources.Requirement` instance


if self.new_version:<EOL><INDENT>return pkg_resources.Requirement.parse(self.name + '<STR_LIT>'.join(self.new_version))<EOL><DEDENT>else:<EOL><INDENT>return pkg_resources.Requirement.parse(self.name)<EOL><DEDENT>

Convert back to a :class:`pkg_resources.Requirement` instance


reqs = req if isinstance(req, list) else [req]<EOL>for req in reqs:<EOL><INDENT>if not isinstance(req, BumpRequirement):<EOL><INDENT>req = BumpRequirement(req)<EOL><DEDENT>req.required = True<EOL>req.required_by = self<EOL>self.requirements.append(req)<EOL><DEDENT>

Add new requirements that must be fulfilled for this bump to occur


requirements = []<EOL>reqs_set = set()<EOL>if isinstance(changes, str):<EOL><INDENT>changes = changes.split('<STR_LIT:\n>')<EOL><DEDENT>if not changes or changes[<NUM_LIT:0>].startswith('<STR_LIT:->'):<EOL><INDENT>return requirements<EOL><DEDENT>for line in changes:<EOL><INDENT>line = line.strip('<STR_LIT>')<EOL>if not line:<EOL><INDENT>continue<EOL><DEDENT>match = IS_REQUIREMENTS_RE2.search(line)  <EOL>if match:<EOL><INDENT>for match in REQUIREMENTS_RE.findall(match.group(<NUM_LIT:1>)):<EOL><INDENT>if match[<NUM_LIT:1>]:<EOL><INDENT>version = '<STR_LIT>' + match[<NUM_LIT:2>] if match[<NUM_LIT:1>].startswith('<STR_LIT>') else match[<NUM_LIT:1>]<EOL>req_str = match[<NUM_LIT:0>] + version<EOL><DEDENT>else:<EOL><INDENT>req_str = match[<NUM_LIT:0>]<EOL><DEDENT>if req_str not in reqs_set:<EOL><INDENT>reqs_set.add(req_str)<EOL>try:<EOL><INDENT>requirements.append(pkg_resources.Requirement.parse(req_str))<EOL><DEDENT>except Exception as e:<EOL><INDENT>log.warn('<STR_LIT>', req_str, e)<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>return requirements<EOL>

Parse changes for requirements

:param list changes:


raise NotImplementedError<EOL>


@classmethod<EOL><INDENT>def bump_message(self, bumps, include_changes=False):<DEDENT>

raise NotImplementedError<EOL>

Compose a bump message for the given bumps

:param list bumps: List of :class:`Bump` instances
:param bool include_changes: Indicate if the message should include detailed changes.


raise NotImplementedError<EOL>

Return a list of existing requirements (as :class:`pkg_resources.Requirement`)


raise NotImplementedError<EOL>

Update/persist requirements from `self.bumps`


def _package_changes(self, name, current_version, new_version):

raise NotImplementedError<EOL>

List of changes for package name from current_version to new_version, in descending order.

:param str name: Name of package
:param current_version: Current version
:param new_version: New version. It is guaranteed to be higher than current version.


raise NotImplementedError<EOL>

List of all versions, in descending order, for the given package name.


return False<EOL>

Should requirement be pinned? This should be True for leaf products.


def package_changes(self, name, current_version, new_version):

if pkg_resources.parse_version(current_version) > pkg_resources.parse_version(new_version):<EOL><INDENT>downgrade_sign = '<STR_LIT>'<EOL>(current_version, new_version) = (new_version, current_version)<EOL><DEDENT>else:<EOL><INDENT>downgrade_sign = None<EOL><DEDENT>changes = self._package_changes(name, current_version, new_version)<EOL>if changes and downgrade_sign:<EOL><INDENT>changes = [downgrade_sign + c for c in changes]<EOL><DEDENT>return changes<EOL>

List of changes for package name from current_version to new_version, in descending order.
If current version is higher than new version (downgrade), then a minus sign will be prefixed to each change.


def _bump(self, existing_req=None, bump_reqs=None):

if existing_req or bump_reqs and any(r.required for r in bump_reqs):<EOL><INDENT>name = existing_req and existing_req.project_name or bump_reqs[<NUM_LIT:0>].project_name<EOL>log.info('<STR_LIT>', name)<EOL>bump = current_version = new_version = None<EOL>if bump_reqs:<EOL><INDENT>if self.should_pin() and (len(bump_reqs) > <NUM_LIT:1> or bump_reqs[<NUM_LIT:0>] and<EOL>bump_reqs[<NUM_LIT:0>].specs and bump_reqs[<NUM_LIT:0>].specs[<NUM_LIT:0>][<NUM_LIT:0>] != '<STR_LIT>'):<EOL><INDENT>log.debug('<STR_LIT>', bump_reqs)<EOL>new_version = self.latest_version_for_requirements(bump_reqs)<EOL>current_version = (existing_req and existing_req.specs and existing_req.specs[<NUM_LIT:0>][<NUM_LIT:0>] == '<STR_LIT>' and<EOL>existing_req.specs[<NUM_LIT:0>][<NUM_LIT:1>])<EOL>if current_version == new_version:<EOL><INDENT>return None<EOL><DEDENT>bump = Bump(name, ('<STR_LIT>', new_version))<EOL><DEDENT>elif len(bump_reqs) > <NUM_LIT:1>:<EOL><INDENT>raise BumpAccident('<STR_LIT>' % (<EOL>name, '<STR_LIT:U+002CU+0020>'.join(str(r) for r in bump_reqs)))<EOL><DEDENT>elif bump_reqs[<NUM_LIT:0>].specs or not (existing_req or self.should_pin() or bump_reqs[<NUM_LIT:0>].specs):<EOL><INDENT>log.debug('<STR_LIT>', bump_reqs)<EOL>latest_version = self.latest_version_for_requirements(bump_reqs)<EOL>new_version = (bump_reqs[<NUM_LIT:0>].specs and bump_reqs[<NUM_LIT:0>].specs[<NUM_LIT:0>][<NUM_LIT:0>] == '<STR_LIT>' and<EOL>bump_reqs[<NUM_LIT:0>].specs[<NUM_LIT:0>][<NUM_LIT:1>] or latest_version)<EOL>current_version = (existing_req and existing_req.specs and existing_req.specs[<NUM_LIT:0>][<NUM_LIT:0>] == '<STR_LIT>' and<EOL>existing_req.specs[<NUM_LIT:0>][<NUM_LIT:1>])<EOL>if current_version == new_version:<EOL><INDENT>return None<EOL><DEDENT>if len(bump_reqs[<NUM_LIT:0>].specs) > <NUM_LIT:1>:<EOL><INDENT>version = ('<STR_LIT:U+002C>'.join(s[<NUM_LIT:0>] + s[<NUM_LIT:1>] for s in bump_reqs[<NUM_LIT:0>].specs),)<EOL><DEDENT>elif bump_reqs[<NUM_LIT:0>].specs:<EOL><INDENT>version = bump_reqs[<NUM_LIT:0>].specs[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>version = None<EOL><DEDENT>bump = Bump(name, version)<EOL><DEDENT><DEDENT>if not bump and (existing_req and existing_req.specs and existing_req.specs[<NUM_LIT:0>][<NUM_LIT:0>] == '<STR_LIT>' or<EOL>self.should_pin() and not existing_req):<EOL><INDENT>log.debug('<STR_LIT>', bump_reqs or name)<EOL>current_version = existing_req and existing_req.specs[<NUM_LIT:0>][<NUM_LIT:1>]<EOL>new_version = self.latest_package_version(name)<EOL>if current_version == new_version:<EOL><INDENT>return None<EOL><DEDENT>if not new_version:<EOL><INDENT>raise BumpAccident('<STR_LIT>' % name)<EOL><DEDENT>bump = Bump(name, ('<STR_LIT>', new_version))<EOL><DEDENT>if bump and current_version and new_version and self.detail:<EOL><INDENT>changes = self.package_changes(bump.name, current_version, new_version)<EOL>bump.changes.extend(changes)<EOL>if self.should_pin():<EOL><INDENT>bump.require(self.requirements_for_changes(changes))<EOL><DEDENT><DEDENT>if bump:<EOL><INDENT>log.debug('<STR_LIT>', bump)<EOL>if bump.requirements:<EOL><INDENT>log.info('<STR_LIT>',<EOL>bump.name, '<STR_LIT:U+002CU+0020>'.join(sorted(str(r) for r in bump.requirements)))<EOL><DEDENT><DEDENT>return bump if str(bump) != str(existing_req) else None<EOL><DEDENT>

Bump an existing requirement to the desired requirement if any.
Subclass can override this `_bump` method to change how each requirement is bumped.

BR = Bump to Requested Version
BL = Bump to Latest Version
BLR = Bump to Latest Version per Requested Requirement
BROL = Bump to Requested Version or Latest (if Pin)
N = No Bump
ERR = Error
C = Version Conflict

Pin case "requires=" will be required.
Filter case "requires=" will be:
   1) From user = Required
   2) From bump = bump/require if existing = One, otherwise print warning.

Filter Case::
    Bump:    None  Any  One  Many
Existing:
     None    N     N    N    N
      Any    N     N    BR   BR
      One    BL    BL   BR   BR
     Many    N     N    BR   BR

Pin Case::
    Bump:    None  Any  One  Many
Existing:
     None    N     N    N    N
      Any    N     N    BR   BLR*
      One    BL    BL   BR   BLR*
     Many    N     N    BR   BLR*

Add/Require Case::
    Bump:    None  Any  One  Many
Existing:
     None    N     BROL BROL BROL

:param pkg_resources.Requirement existing_req: Existing requirement if any
:param list bump_reqs: List of `BumpRequirement`
:return Bump: Either a :class:`Bump` instance or None
:raise BumpAccident:


def bump(self, bump_reqs=None, **kwargs):

bumps = {}<EOL>for existing_req in sorted(self.requirements(), key=lambda r: r.project_name):<EOL><INDENT>if bump_reqs and existing_req.project_name not in bump_reqs:<EOL><INDENT>continue<EOL><DEDENT>bump_reqs.check(existing_req)<EOL>try:<EOL><INDENT>bump = self._bump(existing_req, bump_reqs.get(existing_req.project_name))<EOL>if bump:<EOL><INDENT>bumps[bump.name] = bump<EOL>bump_reqs.check(bump)<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>if bump_reqs and bump_reqs.get(existing_req.project_name) and all(<EOL>r.required_by is None for r in bump_reqs.get(existing_req.project_name)):<EOL><INDENT>raise<EOL><DEDENT>else:<EOL><INDENT>log.warn(e)<EOL><DEDENT><DEDENT><DEDENT>for reqs in bump_reqs.required_requirements().values():<EOL><INDENT>name = reqs[<NUM_LIT:0>].project_name<EOL>if name not in bumps and self.should_add(name):<EOL><INDENT>try:<EOL><INDENT>bump = self._bump(None, reqs)<EOL>if bump:<EOL><INDENT>bumps[bump.name] = bump<EOL>bump_reqs.check(bump)<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>if all(r.required_by is None for r in reqs):<EOL><INDENT>raise<EOL><DEDENT>else:<EOL><INDENT>log.warn(e)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>self.bumps.update(bumps.values())<EOL>return bumps.values()<EOL>

Bump dependencies using given requirements.

:param RequirementsManager bump_reqs: Bump requirements manager
:param dict kwargs: Additional args from argparse. Some bumpers accept user options, and some not.
:return: List of :class:`Bump` changes made.


if self._original_target_content:<EOL><INDENT>with open(self.target, '<STR_LIT:w>') as fp:<EOL><INDENT>fp.write(self._original_target_content)<EOL><DEDENT><DEDENT>

Restore content in target file to be before any changes


return True<EOL>

Should this bumper try to add the given name if requested.


parser = argparse.ArgumentParser(description=bump.__doc__)<EOL>parser.add_argument('<STR_LIT>', nargs='<STR_LIT:*>', help="""<STR_LIT>""")<EOL>parser.add_argument('<STR_LIT>', '<STR_LIT>', action='<STR_LIT:store_true>',<EOL>help='<STR_LIT>')<EOL>parser.add_argument('<STR_LIT>', help='<STR_LIT>')<EOL>parser.add_argument('<STR_LIT>', action='<STR_LIT:store_true>',<EOL>help='<STR_LIT>')<EOL>parser.add_argument('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', action='<STR_LIT:store_true>',<EOL>help='<STR_LIT>'<EOL>'<STR_LIT>')<EOL>parser.add_argument('<STR_LIT>', '<STR_LIT>', action='<STR_LIT:store_true>', help='<STR_LIT>')<EOL>parser.add_argument('<STR_LIT>', action='<STR_LIT:store_true>', help='<STR_LIT>')<EOL>args = parser.parse_args()<EOL>targets = [args.file] if args.file else ['<STR_LIT>', '<STR_LIT>']<EOL>level = logging.DEBUG if args.debug else logging.INFO<EOL>logging.basicConfig(level=level, format='<STR_LIT>')<EOL>try:<EOL><INDENT>bumper = BumperDriver(targets, full_throttle=args.force, detail=args.detail, test_drive=args.dry_run)<EOL>bumper.bump(args.names, required=args.add, show_detail=args.detail)<EOL><DEDENT>except Exception as e:<EOL><INDENT>if args.debug:<EOL><INDENT>raise<EOL><DEDENT>else:<EOL><INDENT>log.error(e)<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT><DEDENT>

CLI entry point to bump requirements in requirements.txt or pinned.txt