Skip to content

Commit e3f8cb3

Browse files
authored
Fix RuntimeError: maximum recursion depth exceeded in cmp happened (appium#343)
* fix maximum recursion depth exceeded in sub classes * add docstring * add comparison of a number of commands * use issubclass to ensure the class is sub
1 parent 1830af4 commit e3f8cb3

2 files changed

Lines changed: 102 additions & 2 deletions

File tree

appium/webdriver/webdriver.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,8 +596,10 @@ def battery_info(self):
596596
# pylint: disable=protected-access
597597

598598
def _addCommands(self):
599-
# call the overridden command binders from all mixin classes
600-
for mixin_class in filter(lambda x: x is not self.__class__, self.__class__.__mro__):
599+
# call the overridden command binders from all mixin classes except for
600+
# appium.webdriver.webdriver.WebDriver and its sub-classes
601+
# https://github.com/appium/python-client/issues/342
602+
for mixin_class in filter(lambda x: not issubclass(x, WebDriver), self.__class__.__mro__):
601603
if hasattr(mixin_class, self._addCommands.__name__):
602604
getattr(mixin_class, self._addCommands.__name__, None)(self)
603605

test/unit/webdriver/webdriver_test.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
android_w3c_driver,
2424
get_httpretty_request_body
2525
)
26+
from appium.webdriver.webdriver import WebDriver
2627

2728

2829
class TestWebDriverWebDriver(object):
@@ -251,3 +252,100 @@ def test_create_session_register_uridirect_no_direct_connect_path(self):
251252

252253
assert 'http://localhost:4723/wd/hub' == driver.command_executor._url
253254
assert ['NATIVE_APP', 'CHROMIUM'] == driver.contexts
255+
256+
257+
class SubWebDriver(WebDriver):
258+
def __init__(self, command_executor, desired_capabilities, direct_connection=False):
259+
super(SubWebDriver, self).__init__(
260+
command_executor=command_executor,
261+
desired_capabilities=desired_capabilities,
262+
direct_connection=direct_connection
263+
)
264+
265+
266+
class SubSubWebDriver(SubWebDriver):
267+
def __init__(self, command_executor, desired_capabilities, direct_connection=False):
268+
super(SubSubWebDriver, self).__init__(
269+
command_executor=command_executor,
270+
desired_capabilities=desired_capabilities,
271+
direct_connection=direct_connection
272+
)
273+
274+
275+
class TestSubModuleWebDriver(object):
276+
def android_w3c_driver(self, driver_class):
277+
response_body_json = json.dumps(
278+
{
279+
'value': {
280+
'sessionId': '1234567890',
281+
'capabilities': {
282+
'platform': 'LINUX',
283+
'desired': {
284+
'platformName': 'Android',
285+
'automationName': 'uiautomator2',
286+
'platformVersion': '7.1.1',
287+
'deviceName': 'Android Emulator',
288+
'app': '/test/apps/ApiDemos-debug.apk',
289+
},
290+
'platformName': 'Android',
291+
'automationName': 'uiautomator2',
292+
'platformVersion': '7.1.1',
293+
'deviceName': 'emulator-5554',
294+
'app': '/test/apps/ApiDemos-debug.apk',
295+
'deviceUDID': 'emulator-5554',
296+
'appPackage': 'com.example.android.apis',
297+
'appWaitPackage': 'com.example.android.apis',
298+
'appActivity': 'com.example.android.apis.ApiDemos',
299+
'appWaitActivity': 'com.example.android.apis.ApiDemos'
300+
}
301+
}
302+
}
303+
)
304+
305+
httpretty.register_uri(
306+
httpretty.POST,
307+
appium_command('/session'),
308+
body=response_body_json
309+
)
310+
311+
desired_caps = {
312+
'platformName': 'Android',
313+
'deviceName': 'Android Emulator',
314+
'app': 'path/to/app',
315+
'automationName': 'UIAutomator2'
316+
}
317+
318+
driver = driver_class(
319+
'http://localhost:4723/wd/hub',
320+
desired_caps
321+
)
322+
return driver
323+
324+
@httpretty.activate
325+
def test_clipboard_with_subclass(self):
326+
driver = self.android_w3c_driver(SubWebDriver)
327+
httpretty.register_uri(
328+
httpretty.GET,
329+
appium_command('/session/1234567890/context'),
330+
body='{"value": "NATIVE"}'
331+
)
332+
assert driver.current_context == 'NATIVE'
333+
334+
@httpretty.activate
335+
def test_clipboard_with_subsubclass(self):
336+
driver = self.android_w3c_driver(SubSubWebDriver)
337+
httpretty.register_uri(
338+
httpretty.GET,
339+
appium_command('/session/1234567890/context'),
340+
body='{"value": "NATIVE"}'
341+
)
342+
assert driver.current_context == 'NATIVE'
343+
344+
@httpretty.activate
345+
def test_compare_commands(self):
346+
driver_base = android_w3c_driver()
347+
driver_sub = self.android_w3c_driver(SubWebDriver)
348+
driver_subsub = self.android_w3c_driver(SubSubWebDriver)
349+
350+
assert len(driver_base.command_executor._commands) == len(driver_sub.command_executor._commands)
351+
assert len(driver_base.command_executor._commands) == len(driver_subsub.command_executor._commands)

0 commit comments

Comments
 (0)