简体   繁体   中英

Python: RecursionError: maximum recursion depth exceeded while calling a Python object

The code i've been buidling came across this error today and i cant figure out whats wrong and why its happening.

The error:

Traceback (most recent call last):
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 63, in loop
    last_msg()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 35, in last_msg
    loop()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 63, in loop
    last_msg()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 35, in last_msg
    loop()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 61, in loop
    open_chatroom()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 21, in open_chatroom
    WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CLASS_NAME, '_1ZMSM')))
  File "D:\py\lib\site-packages\selenium\webdriver\support\wait.py", line 71, in until
    value = method(self._driver)
  File "D:\py\lib\site-packages\selenium\webdriver\support\expected_conditions.py", line 64, in __call__
    return _find_element(driver, self.locator)
  File "D:\py\lib\site-packages\selenium\webdriver\support\expected_conditions.py", line 411, in _find_element
    return driver.find_element(*by)
  File "D:\py\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
    'value': value})['value']
  File "D:\py\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 319, in execute
    response = self.command_executor.execute(driver_command, params)
  File "D:\py\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 374, in execute
    return self._request(command_info[0], url, body=data)
  File "D:\py\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 397, in _request
    resp = self._conn.request(method, url, body=body, headers=headers)
  File "D:\py\lib\site-packages\urllib3\request.py", line 80, in request
    method, url, fields=fields, headers=headers, **urlopen_kw
  File "D:\py\lib\site-packages\urllib3\request.py", line 171, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
  File "D:\py\lib\site-packages\urllib3\poolmanager.py", line 330, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "D:\py\lib\site-packages\urllib3\connectionpool.py", line 672, in urlopen
    chunked=chunked,
  File "D:\py\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "D:\py\lib\site-packages\urllib3\connectionpool.py", line 416, in _make_request
    httplib_response = conn.getresponse()
  File "D:\py\lib\http\client.py", line 1321, in getresponse
    response.begin()
  File "D:\py\lib\http\client.py", line 320, in begin
    self.headers = self.msg = parse_headers(self.fp)
  File "D:\py\lib\http\client.py", line 214, in parse_headers
    return email.parser.Parser(_class=_class).parsestr(hstring)
  File "D:\py\lib\email\parser.py", line 68, in parsestr
    return self.parse(StringIO(text), headersonly=headersonly)
  File "D:\py\lib\email\parser.py", line 57, in parse
    feedparser.feed(data)
  File "D:\py\lib\email\feedparser.py", line 176, in feed
    self._call_parse()
  File "D:\py\lib\email\feedparser.py", line 180, in _call_parse
    self._parse()
  File "D:\py\lib\email\feedparser.py", line 295, in _parsegen
    if self._cur.get_content_maintype() == 'message':
  File "D:\py\lib\email\message.py", line 594, in get_content_maintype
    ctype = self.get_content_type()
  File "D:\py\lib\email\message.py", line 578, in get_content_type
    value = self.get('content-type', missing)
  File "D:\py\lib\email\message.py", line 471, in get
    return self.policy.header_fetch_parse(k, v)
  File "D:\py\lib\email\_policybase.py", line 316, in header_fetch_parse
    return self._sanitize_header(name, value)
  File "D:\py\lib\email\_policybase.py", line 287, in _sanitize_header
    if _has_surrogates(value):
  File "D:\py\lib\email\utils.py", line 57, in _has_surrogates
    s.encode()
RecursionError: maximum recursion depth exceeded while calling a Python object

Process finished with exit code 1

This will get the last unread message.

def w:
    try:
        post = driver.find_elements_by_class_name("_12pGw")
        ultimo = len(post) - 1
        texto = post[ultimo].find_element_by_css_selector(
            "span.selectable-text").text
        return texto
    except Exception:
        loop()

This creates a dictionary from a pandas df and replies the user with matching answer.

def y:
    df = pd.read_excel(r'D:\Drive\Outros\Python\Project\Dict.xlsx', error_bad_lines=False, encoding='utf-8-sig')
    d = df.set_index('msg')['reply'].to_dict()
    try:
        input_field = driver.find_element_by_class_name("_3u328")
        try:
            x = next(v for k, v in d.items() if last_msg() in k)
        except StopIteration:
            x = 'Não entendi, este comando é invalido'
        input_field.send_keys(x)
        time.sleep(1)
        driver.find_element_by_class_name("_3M-N-").click()
        try:
            driver.find_element_by_class_name("_2zCfw").send_keys('Lonely bot')
            driver.find_element_by_xpath("//span[@title = '{}']".format('Lonely bot')).click()
            driver.find_element_by_class_name("_2heX1").click()
            WebDriverWait(driver, 600).until(EC.invisibility_of_element_located((By.NAME, "status-time")))
        except TimeoutException:
            loop()
    except NoSuchElementException:
        loop()

Here i defined a loop to keep the code online

def loop:
    try:
        z()
        time.sleep(1)
        w()
        y()
        driver.refresh()
    except TimeoutException:
        loop()

This is the first read and reply.

while True:
    try:
        open_chatroom()
        time.sleep(1)
        w()
        y()
        driver.refresh()
    except TimeoutException:
        loop()

I never experienced this before. How can i change my code so my loop doesnt break with this error?

At your exception handler, your function loop calls itself. every TimeoutException exception you creating a new stack frame, and I guess these stack frames are never emptied, eventually causing a RecursionError .

Looking at the last few items in the traceback, it seems that loop and last_msg are calling each other repeatedly, so the there is a recursion that involves two routines instead of just one calling itself. There's also a similar possible cycle through the functions loop and conversation .

The goal is to keep the chatbot running in a loop all the time, even if you hit an error of some kind, but the problem arises when loop gets called again in the exception handlers. It starts another copy of loop inside last_msg while the first copy of loop is still running. So last_msg calls loop and that in turn calls last_msg again, and none of the calls ever finish, they just pile up until you run ouf of space.

The way to solve this is to just return from the function where you catch the exception, and to replace the loop function with a while True: loop (just like the last code block in the original question).

Catching the exceptions prevents them from stopping the while loop. If something does fail then the while loop will keep trying again forever, but then it's doing it forever inside one function call, rather than a new recursive call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM