1

I'm trying to learn selenium for automating some stuff and I get the following error

Exception ignored in: <function bot.del at 0x0351BF10>
Traceback (most recent call last):
File "main.py", line 52, in del
File "C:\Users\michael-blaze\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 158, in quit
File "C:\Users\michael-blaze\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\common\service.py", line 151, in stop
File "C:\Users\michael-blaze\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\common\service.py", line 122, in send_remote_shutdown_command
ImportError: sys.meta_path is None, Python is likely shutting down

I figured it out the line where it comes from

def __del__(self):
   self.driver.quit()

My init function looks something like this

def __init__(self):
   self.driver = webdriver.Chrome(path)

What would cause this problem ?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
royer
  • 35
  • 1
  • 7
  • Does this answer your question? [ImportError: sys.meta\_path is None, Python is likely shutting down](https://stackoverflow.com/questions/41480148/importerror-sys-meta-path-is-none-python-is-likely-shutting-down) – running.t Jul 24 '20 at 12:56
  • Initially i read that post but it didn't solve my question unfortunately – royer Jul 24 '20 at 13:00
  • Can you rethink your code to use `with webdriver.Chrome(path):` instead? that should clean up properly at the end – Alessio Arena Jul 24 '20 at 13:18
  • I'm still a noob with python. Can you be more specific when you say use 'with webdriver.Chrome(path)' :) – royer Jul 24 '20 at 13:21
  • self.driver.close() works but it doesn't free up memory running.t – royer Jul 24 '20 at 13:23

2 Answers2

1

I was able to reproduce your issue. Here are the observations:

  • Code Block:

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
    class PythonBot:
        def __init__(self,my_string):
        self.my_string = my_string
        self.driver = webdriver.Chrome(executable_path=r'C:\WebDrivers\chromedriver.exe')
    
        def send_text(self):
        driver = self.driver
        driver.get('https://www.google.com/')
        WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, "q"))).send_keys(self.my_string)
    
        def __del__(self):
        self.driver.quit()
    
    run = PythonBot('Selenium')
    run.send_text()
    
  • Console Output:

    Exception ignored in: <bound method PythonBot.__del__ of <__main__.PythonBot object at 0x028172F0>>
    Traceback (most recent call last):
      File "C:\Users\Soma Bhattacharjee\Desktop\Debanjan\PyPrograms\init_del_in_python_class.py", line 17, in __del__
      File "C:\Python\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 158, in quit
      File "C:\Python\lib\site-packages\selenium\webdriver\common\service.py", line 151, in stop
      File "C:\Python\lib\site-packages\selenium\webdriver\common\service.py", line 122, in send_remote_shutdown_command
    ImportError: sys.meta_path is None, Python is likely shutting down
    

Analysis

This issue was earlier reported and discussed within sys.meta_path is None, Python is likely shutting down. Accordingly a commit was merged which mentions:

Changes the order of events to stop a process. Previously. the order was terminate() -> kill() -> wait(). So... it would send a SIGTERM signal to the process, immediately followed by a SIGKILL signal. Since wait() is called after the process has already been forcefully stopped, there is nothing to wait on, so it does nothing. The proper sequence should be: terminate() -> wait() -> kill(). That will send a SIGINT, wait for graceful process termination, then send a SIGKILL to forcefully stop it as a last resort.

However, this issue still seems to be surfacing when using self.driver.quit() within def __del__(self):

Reported this issue in:


Interim Solution

An interim solution would be to call self.driver.close() within def __del__(self): as follows:

def __del__(self):
    self.driver.close()
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
0

See if you can structure you code like this:

# stuff before the driver call
with webdriver.Chrome(path) as driver:
    # do your stuff here
    # you can access the driver using the variable 'driver'
# stuff after the driver call

In this way once the with block is finished, the driver should be cleaned in the best way possible, including forcing Python to wait until closed.

disclaimer: I haven't tested it, just noticed that they have the __enter__ and __exit__ methods implemented

Alessio Arena
  • 390
  • 2
  • 8
  • your approuch works perfectly but i still wonder why self.driver.quit() doesn't work inside my __del__ destructor function. I wanted to use classes. – royer Jul 24 '20 at 13:42
  • this may be a good reference to understand that problem: https://stackoverflow.com/questions/14986568/python-how-to-ensure-that-del-method-of-an-object-is-called-before-the-mod. Basically, once you get to `__del__` your interpreter already cleaned up some things. Looking into the code, seems that there are some modules that are imported within the `quit` command, and that may be too late to do that as well – Alessio Arena Jul 26 '20 at 01:56