Skip to content

Commit e911457

Browse files
fix: Tune mixin types, so linters could recognize them better (appium#536)
1 parent 75e7b6e commit e911457

31 files changed

+312
-211
lines changed

appium/webdriver/extensions/action_helpers.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import TYPE_CHECKING, List, Optional, Tuple, TypeVar
15+
from typing import TYPE_CHECKING, List, Optional, Tuple, TypeVar, Union
1616

1717
from selenium import webdriver
1818

@@ -21,20 +21,21 @@
2121
from appium.webdriver.webelement import WebElement
2222

2323
if TYPE_CHECKING:
24+
# noinspection PyUnresolvedReferences
2425
from appium.webdriver.webdriver import WebDriver
2526

26-
T = TypeVar('T', bound='WebDriver')
27+
T = TypeVar('T', bound=Union['WebDriver', 'ActionHelpers'])
2728

2829

2930
class ActionHelpers(webdriver.Remote):
3031

31-
def scroll(self, origin_el: WebElement, destination_el: WebElement, duration: Optional[int] = None) -> T:
32+
def scroll(self: T, origin_el: WebElement, destination_el: WebElement, duration: Optional[int] = None) -> T:
3233
"""Scrolls from one element to another
3334
3435
Args:
35-
originalEl (`appium.webdriver.webelement.WebElement`): the element from which to being scrolling
36-
destinationEl (`appium.webdriver.webelement.WebElement`): the element to scroll to
37-
duration (int): a duration after pressing originalEl and move the element to destinationEl.
36+
origin_el: the element from which to being scrolling
37+
destination_el: the element to scroll to
38+
duration: a duration after pressing originalEl and move the element to destinationEl.
3839
Default is 600 ms for W3C spec. Zero for MJSONWP.
3940
4041
Usage:
@@ -55,12 +56,12 @@ def scroll(self, origin_el: WebElement, destination_el: WebElement, duration: Op
5556
action.press(origin_el).wait(duration).move_to(destination_el).release().perform()
5657
return self
5758

58-
def drag_and_drop(self, origin_el: WebElement, destination_el: WebElement) -> T:
59+
def drag_and_drop(self: T, origin_el: WebElement, destination_el: WebElement) -> T:
5960
"""Drag the origin element to the destination element
6061
6162
Args:
62-
originEl (`appium.webdriver.webelement.WebElement`): the element to drag
63-
destinationEl (`appium.webdriver.webelement.WebElement`): the element to drag to
63+
origin_el: the element to drag
64+
destination_el: the element to drag to
6465
6566
Returns:
6667
`appium.webdriver.webelement.WebElement`
@@ -69,7 +70,7 @@ def drag_and_drop(self, origin_el: WebElement, destination_el: WebElement) -> T:
6970
action.long_press(origin_el).move_to(destination_el).release().perform()
7071
return self
7172

72-
def tap(self, positions: List[Tuple[int, int]], duration: Optional[int] = None) -> T:
73+
def tap(self: T, positions: List[Tuple[int, int]], duration: Optional[int] = None) -> T:
7374
"""Taps on an particular place with up to five fingers, holding for a
7475
certain time
7576
@@ -108,7 +109,7 @@ def tap(self, positions: List[Tuple[int, int]], duration: Optional[int] = None)
108109
ma.perform()
109110
return self
110111

111-
def swipe(self, start_x: int, start_y: int, end_x: int, end_y: int, duration: int = 0) -> T:
112+
def swipe(self: T, start_x: int, start_y: int, end_x: int, end_y: int, duration: int = 0) -> T:
112113
"""Swipe from one point to another point, for an optional duration.
113114
114115
Args:
@@ -135,7 +136,7 @@ def swipe(self, start_x: int, start_y: int, end_x: int, end_y: int, duration: in
135136
action.perform()
136137
return self
137138

138-
def flick(self, start_x: int, start_y: int, end_x: int, end_y: int) -> T:
139+
def flick(self: T, start_x: int, start_y: int, end_x: int, end_y: int) -> T:
139140
"""Flick from one point to another point.
140141
141142
Args:

appium/webdriver/extensions/android/activities.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import TYPE_CHECKING, TypeVar
15+
from typing import TYPE_CHECKING, TypeVar, Union
1616

1717
from selenium import webdriver
1818
from selenium.common.exceptions import TimeoutException
@@ -21,13 +21,14 @@
2121
from appium.webdriver.mobilecommand import MobileCommand as Command
2222

2323
if TYPE_CHECKING:
24+
# noinspection PyUnresolvedReferences
2425
from appium.webdriver.webdriver import WebDriver
2526

26-
T = TypeVar('T', bound='WebDriver')
27+
T = TypeVar('T', bound=Union['WebDriver', 'Activities'])
2728

2829

2930
class Activities(webdriver.Remote):
30-
def start_activity(self, app_package: str, app_activity: str, **opts: str) -> T:
31+
def start_activity(self: T, app_package: str, app_activity: str, **opts: str) -> T:
3132
"""Opens an arbitrary activity during a test. If the activity belongs to
3233
another application, that application is started and the activity is opened.
3334
@@ -66,15 +67,15 @@ def start_activity(self, app_package: str, app_activity: str, **opts: str) -> T:
6667
return self
6768

6869
@property
69-
def current_activity(self) -> str:
70+
def current_activity(self: T) -> str:
7071
"""Retrieves the current activity running on the device.
7172
7273
Returns:
7374
str: The current activity name running on the device
7475
"""
7576
return self.execute(Command.GET_CURRENT_ACTIVITY)['value']
7677

77-
def wait_activity(self, activity: str, timeout: int, interval: int = 1) -> bool:
78+
def wait_activity(self: T, activity: str, timeout: int, interval: int = 1) -> bool:
7879
"""Wait for an activity: block until target activity presents or time out.
7980
8081
This is an Android-only method.
@@ -95,7 +96,7 @@ def wait_activity(self, activity: str, timeout: int, interval: int = 1) -> bool:
9596
return False
9697

9798
# pylint: disable=protected-access
98-
99+
# noinspection PyProtectedMember
99100
def _addCommands(self) -> None:
100101
self.command_executor._commands[Command.GET_CURRENT_ACTIVITY] = \
101102
('GET', '/session/$sessionId/appium/device/current_activity')

appium/webdriver/extensions/android/common.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,22 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import TYPE_CHECKING, Any, TypeVar
15+
from typing import TYPE_CHECKING, Any, TypeVar, Union
1616

1717
from selenium import webdriver
1818

1919
from appium.webdriver.mobilecommand import MobileCommand as Command
2020

2121
if TYPE_CHECKING:
22+
# noinspection PyUnresolvedReferences
2223
from appium.webdriver.webdriver import WebDriver
2324

24-
T = TypeVar('T', bound='WebDriver')
25+
T = TypeVar('T', bound=Union['WebDriver', 'Common'])
2526

2627

2728
class Common(webdriver.Remote):
2829

29-
def end_test_coverage(self, intent: str, path: str) -> Any: # TODO Check return type
30+
def end_test_coverage(self: T, intent: str, path: str) -> Any: # TODO Check return type
3031
"""Ends the coverage collection and pull the coverage.ec file from the device.
3132
3233
Android only.
@@ -45,7 +46,7 @@ def end_test_coverage(self, intent: str, path: str) -> Any: # TODO Check return
4546
}
4647
return self.execute(Command.END_TEST_COVERAGE, data)['value']
4748

48-
def open_notifications(self) -> T:
49+
def open_notifications(self: T) -> T:
4950
"""Open notification shade in Android (API Level 18 and above)
5051
5152
Returns:
@@ -55,11 +56,12 @@ def open_notifications(self) -> T:
5556
return self
5657

5758
@property
58-
def current_package(self) -> str:
59+
def current_package(self: T) -> str:
5960
"""Retrieves the current package running on the device.
6061
"""
6162
return self.execute(Command.GET_CURRENT_PACKAGE)['value']
6263

64+
# noinspection PyProtectedMember
6365
def _addCommands(self) -> None:
6466
self.command_executor._commands[Command.GET_CURRENT_PACKAGE] = \
6567
('GET', '/session/$sessionId/appium/device/current_package')

appium/webdriver/extensions/android/display.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,22 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from typing import TYPE_CHECKING, TypeVar, Union
16+
1517
from selenium import webdriver
1618

1719
from appium.webdriver.mobilecommand import MobileCommand as Command
1820

21+
if TYPE_CHECKING:
22+
# noinspection PyUnresolvedReferences
23+
from appium.webdriver.webdriver import WebDriver
24+
25+
T = TypeVar('T', bound=Union['WebDriver', 'Display'])
26+
1927

2028
class Display(webdriver.Remote):
2129

22-
def get_display_density(self) -> int:
30+
def get_display_density(self: T) -> int:
2331
"""Get the display density, Android only
2432
2533
Returns:
@@ -31,7 +39,7 @@ def get_display_density(self) -> int:
3139
return self.execute(Command.GET_DISPLAY_DENSITY)['value']
3240

3341
# pylint: disable=protected-access
34-
42+
# noinspection PyProtectedMember
3543
def _addCommands(self) -> None:
3644
self.command_executor._commands[Command.GET_DISPLAY_DENSITY] = \
3745
('GET', '/session/$sessionId/appium/device/display_density')

appium/webdriver/extensions/android/gsm.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import TYPE_CHECKING, TypeVar
15+
from typing import TYPE_CHECKING, TypeVar, Union
1616

1717
from selenium import webdriver
1818

@@ -21,8 +21,11 @@
2121
from appium.webdriver.mobilecommand import MobileCommand as Command
2222

2323
if TYPE_CHECKING:
24+
# noinspection PyUnresolvedReferences
2425
from appium.webdriver.webdriver import WebDriver
2526

27+
T = TypeVar('T', bound=Union['WebDriver', 'Gsm'])
28+
2629

2730
class GsmCallActions:
2831
CALL = 'call'
@@ -49,12 +52,9 @@ class GsmVoiceState:
4952
ON = 'on'
5053

5154

52-
T = TypeVar('T', bound='WebDriver')
53-
54-
5555
class Gsm(webdriver.Remote):
5656

57-
def make_gsm_call(self, phone_number: str, action: str) -> T:
57+
def make_gsm_call(self: T, phone_number: str, action: str) -> T:
5858
"""Make GSM call (Emulator only)
5959
6060
Android only.
@@ -70,11 +70,12 @@ def make_gsm_call(self, phone_number: str, action: str) -> T:
7070
constants = extract_const_attributes(GsmCallActions)
7171
if action not in constants.values():
7272
logger.warning(
73-
f'{action} is unknown. Consider using one of {list(constants.keys())} constants. (e.g. {GsmCallActions.__name__}.CALL)')
73+
f'{action} is unknown. Consider using one of {list(constants.keys())} constants. '
74+
f'(e.g. {GsmCallActions.__name__}.CALL)')
7475
self.execute(Command.MAKE_GSM_CALL, {'phoneNumber': phone_number, 'action': action})
7576
return self
7677

77-
def set_gsm_signal(self, strength: int) -> T:
78+
def set_gsm_signal(self: T, strength: int) -> T:
7879
"""Set GSM signal strength (Emulator only)
7980
8081
Android only.
@@ -89,11 +90,12 @@ def set_gsm_signal(self, strength: int) -> T:
8990
constants = extract_const_attributes(GsmSignalStrength)
9091
if strength not in constants.values():
9192
logger.warning(
92-
f'{strength} is out of range. Consider using one of {list(constants.keys())} constants. (e.g. {GsmSignalStrength.__name__}.GOOD)')
93+
f'{strength} is out of range. Consider using one of {list(constants.keys())} constants. '
94+
f'(e.g. {GsmSignalStrength.__name__}.GOOD)')
9395
self.execute(Command.SET_GSM_SIGNAL, {'signalStrength': strength, 'signalStrengh': strength})
9496
return self
9597

96-
def set_gsm_voice(self, state: str) -> T:
98+
def set_gsm_voice(self: T, state: str) -> T:
9799
"""Set GSM voice state (Emulator only)
98100
99101
Android only.
@@ -108,12 +110,13 @@ def set_gsm_voice(self, state: str) -> T:
108110
constants = extract_const_attributes(GsmVoiceState)
109111
if state not in constants.values():
110112
logger.warning(
111-
f'{state} is unknown. Consider using one of {list(constants.keys())} constants. (e.g. {GsmVoiceState.__name__}.HOME)')
113+
f'{state} is unknown. Consider using one of {list(constants.keys())} constants. '
114+
f'(e.g. {GsmVoiceState.__name__}.HOME)')
112115
self.execute(Command.SET_GSM_VOICE, {'state': state})
113116
return self
114117

115118
# pylint: disable=protected-access
116-
119+
# noinspection PyProtectedMember
117120
def _addCommands(self) -> None:
118121
self.command_executor._commands[Command.MAKE_GSM_CALL] = \
119122
('POST', '/session/$sessionId/appium/device/gsm_call')

appium/webdriver/extensions/android/network.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import TYPE_CHECKING, TypeVar
15+
from typing import TYPE_CHECKING, TypeVar, Union
1616

1717
from selenium import webdriver
1818

@@ -21,9 +21,10 @@
2121
from appium.webdriver.mobilecommand import MobileCommand as Command
2222

2323
if TYPE_CHECKING:
24+
# noinspection PyUnresolvedReferences
2425
from appium.webdriver.webdriver import WebDriver
2526

26-
T = TypeVar('T', bound='WebDriver')
27+
T = TypeVar('T', bound=Union['WebDriver', 'NetSpeed'])
2728

2829

2930
class NetSpeed:
@@ -41,15 +42,15 @@ class NetSpeed:
4142
class Network(webdriver.Remote):
4243

4344
@property
44-
def network_connection(self) -> int:
45+
def network_connection(self: T) -> int:
4546
"""Returns an integer bitmask specifying the network connection type.
4647
4748
Android only.
4849
Possible values are available through the enumeration `appium.webdriver.ConnectionType`
4950
"""
5051
return self.execute(Command.GET_NETWORK_CONNECTION, {})['value']
5152

52-
def set_network_connection(self, connection_type: int) -> int:
53+
def set_network_connection(self: T, connection_type: int) -> int:
5354
"""Sets the network connection type. Android only.
5455
5556
Possible values:
@@ -83,7 +84,7 @@ def set_network_connection(self, connection_type: int) -> int:
8384
}
8485
return self.execute(Command.SET_NETWORK_CONNECTION, data)['value']
8586

86-
def toggle_wifi(self) -> T:
87+
def toggle_wifi(self: T) -> T:
8788
"""Toggle the wifi on the device, Android only.
8889
8990
Returns:
@@ -92,7 +93,7 @@ def toggle_wifi(self) -> T:
9293
self.execute(Command.TOGGLE_WIFI, {})
9394
return self
9495

95-
def set_network_speed(self, speed_type: str) -> T:
96+
def set_network_speed(self: T, speed_type: str) -> T:
9697
"""Set the network speed emulation.
9798
9899
Android Emulator only.
@@ -110,13 +111,14 @@ def set_network_speed(self, speed_type: str) -> T:
110111
constants = extract_const_attributes(NetSpeed)
111112
if speed_type not in constants.values():
112113
logger.warning(
113-
f'{speed_type} is unknown. Consider using one of {list(constants.keys())} constants. (e.g. {NetSpeed.__name__}.LTE)')
114+
f'{speed_type} is unknown. Consider using one of {list(constants.keys())} constants. '
115+
f'(e.g. {NetSpeed.__name__}.LTE)')
114116

115117
self.execute(Command.SET_NETWORK_SPEED, {'netspeed': speed_type})
116118
return self
117119

118120
# pylint: disable=protected-access
119-
121+
# noinspection PyProtectedMember
120122
def _addCommands(self) -> None:
121123
self.command_executor._commands[Command.TOGGLE_WIFI] = \
122124
('POST', '/session/$sessionId/appium/device/toggle_wifi')

0 commit comments

Comments
 (0)