Python pausing Threading - python

I'm really new to python and I don't even know if the title of this python question is even right. Anyways I'm facing an error code that I have been trying to find a fix for in the last couple of hours. The error goes like this: raise RuntimeError("threads can only be started once").
Now I googled the error and I got a couple of solutions. I tried a couple of them and none of them seem to work. I know that you cannot use the start function for more than one time, But how else am I supposed to get my script to work again?
import pyautogui, requests, pyperclip
from pynput import mouse, keyboard
from tkinter import filedialog
url = "https://poxgur.com/"
file_path = filedialog.asksaveasfilename(defaultextension='.png')
def on_click(x, y, button, pressed):
global currentMouseX, currentMouseY
if pressed:
currentMouseX, currentMouseY = x, y
if not pressed:
mouse_listener.stop()
im = pyautogui.screenshot(region=(
currentMouseX, currentMouseY, abs(currentMouseX - x), abs(currentMouseY - y)))
im.save(file_path)
print(file_path)
files = {"file": open(file_path, "rb")}
r = requests.post(url + "api.php", files=files)
pyperclip.copy(url + r.text + ".png")
# os.remove(file_path)
mouse_listener.stop()
return False
mouse_listener = mouse.Listener(on_click=on_click)
def on_scroll_lock_release(key):
if key == keyboard.Key.scroll_lock:
if not mouse_listener.is_alive():
mouse_listener.start()
with keyboard.Listener(on_release=on_scroll_lock_release) as listener:
listener.join()
The error meesage:
Unhandled exception in listener callback
Traceback (most recent call last):
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\site-packages\pynput\_util\__init__.py", line 162, in inner
return f(self, *args, **kwargs)
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\site-packages\pynput\keyboard\_win32.py", line 283, in _process
self.on_release(key)
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\site-packages\pynput\_util\__init__.py", line 78, in inner
if f(*args) is False:
File "C:/Users/marti/Documents/PythonProjects/Acutal Projects/The 100 Projects/Screenshot2.0.py", line 33, in on_scroll_lock_release
mouse_listener.start()
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\threading.py", line 848, in start
raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once
Traceback (most recent call last):
File "C:/Users/marti/Documents/PythonProjects/Acutal Projects/The 100 Projects/Screenshot2.0.py", line 37, in <module>
listener.join()
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\site-packages\pynput\_util\__init__.py", line 210, in join
six.reraise(exc_type, exc_value, exc_traceback)
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\site-packages\six.py", line 702, in reraise
raise value.with_traceback(tb)
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\site-packages\pynput\_util\__init__.py", line 162, in inner
return f(self, *args, **kwargs)
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\site-packages\pynput\keyboard\_win32.py", line 283, in _process
self.on_release(key)
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\site-packages\pynput\_util\__init__.py", line 78, in inner
if f(*args) is False:
File "C:/Users/marti/Documents/PythonProjects/Acutal Projects/The 100 Projects/Screenshot2.0.py", line 33, in on_scroll_lock_release
mouse_listener.start()
File "C:\Users\marti\anaconda3\envs\The 100 Projects\lib\threading.py", line 848, in start
raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once
Process finished with exit code 1

A possible solution would be to intialize a new Listener each time before starting the Listener.
You could re-code your solution in the following way:
mouse_listener = mouse.Listener(on_click=on_click)
def on_scroll_lock_release(key):
if key == keyboard.Key.scroll_lock:
if not mouse_listener.is_alive():
mouse_listener = mouse.Listener(on_click=on_click)
mouse_listener.start()

Related

Python PyAutoGui pixelMatchesColor raises windll.user32.ReleaseDC Error

Been having issues trying to see if a pixel on my screen matches an RGB color. However, even after tweaking I could not get any good results. I looked it up online and tried different solution, but no luck.
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Python38\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Python38\lib\site-packages\keyboard\_generic.py", line 58, in process
if self.pre_process_event(event):
File "C:\Python38\lib\site-packages\keyboard\__init__.py", line 218, in pre_process_event
callback(event)
File "C:\Python38\lib\site-packages\keyboard\__init__.py", line 649, in <lambda>
handler = lambda e: (event_type == KEY_DOWN and e.event_type == KEY_UP and e.scan_code in _logically_pressed_keys) or (event_type == e.event_type and callback())
File "main.py", line 101, in bomb_timer
pix = pyautogui.pixelMatchesColor(959, 83, (169, 0, 0), tolerance=61)
File "C:\Python38\lib\site-packages\pyscreeze\__init__.py", line 559, in pixelMatchesColor
pix = pixel(x, y)
File "C:\Python38\lib\site-packages\pyscreeze\__init__.py", line 584, in pixel
return (r, g, b)
File "C:\Python38\lib\contextlib.py", line 120, in __exit__
next(self.gen)
File "C:\Python38\lib\site-packages\pyscreeze\__init__.py", line 113, in __win32_openDC
raise WindowsError("windll.user32.ReleaseDC failed : return 0")
OSError: windll.user32.ReleaseDC failed : return 0
My code:
def clock_timer():
clock = pyautogui.locateCenterOnScreen('assets/clock2.png', grayscale=True, confidence=0.5, region=(920,10, 90, 90))
print(Style.RESET_ALL + "[" + Fore.RED + "zVal" + Style.RESET_ALL + "]" + Fore.RED + " Waiting for clock...")
while clock == None:
clock1 = pyautogui.locateCenterOnScreen('assets/clock2.png', grayscale=True, confidence=0.5, region=(920,10, 90, 90))
pix = pyautogui.pixelMatchesColor(959, 83, (169, 0, 0), tolerance=61) #PART THAT DOESNT WORK
if clock1 != None and pix == True:
clock = "Stop loop"
Couldn't find the exact reason to why this was happening, but the fix to this was deleting all my Python versions (3.78 & 3.83) then I re-installed 3.83 only. This fixed the problem. Hope this helps anyone else with the issue.
Possible Solutions:
Downgrading from Python 3.8 to 3.7
reinstalling Python
trying it in the python interpreter/ cmd >> python

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.

Memory issue with multiprocessing in Python

I am trying to use my other cores in my python program. And the following is the basic structure/logic of my code:
import multiprocessing as mp
import pandas as pd
import gc
def multiprocess_RUN(param):
result = Analysis_Obj.run(param)
return result
class Analysis_Obj():
def __init__(self, filename):
self.DF = pd.read_csv(filename)
return
def run_Analysis(self, param):
# Multi-core option
pool = mp.Pool(processes=1)
run_result = pool.map(multiprocess_RUN, [self, param])
# Normal option
run_result = self.run(param)
return run_result
def run(self, param):
# Let's say I have written a function to count the frequency of 'param' in the target file
result = count(self.DF, param)
return result
if __name__ == "__main__":
files = ['file1.csv', 'file2.csv']
params = [1,2,3,4]
results = []
for i in range(0,len(files)):
analysis = Analysis_Obj(files[i])
for j in range(0,len(params)):
result = analysis.run_Analysis(params[j])
results.append(result)
del result
del analysis
gc.collect()
If I comment out the 'Multi-core option' and run the 'Normal option' everything runs fine. But even if I run the 'Multi-core option' with processes=1 I get a Memory Error when my for loop starts on the 2nd file. I have deliberately set it up so that I create and delete an Analysis object in each for loop, so that the file that has been processed will be cleared from memory. Clearly this hasn't worked. Advice of how to get around this would be very much appreciated.
Cheers
EDIT:
Here is the error message I have in the terminal:
Exception in thread Thread-7:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib/python2.7/multiprocessing/pool.py", line 326, in _handle_workers
pool._maintain_pool()
File "/usr/lib/python2.7/multiprocessing/pool.py", line 230, in _maintain_pool
self._repopulate_pool()
File "/usr/lib/python2.7/multiprocessing/pool.py", line 223, in _repopulate_pool
w.start()
File "/usr/lib/python2.7/multiprocessing/process.py", line 130, in start
self._popen = Popen(self)
File "/usr/lib/python2.7/multiprocessing/forking.py", line 121, in __init__
self.pid = os.fork()
OSError: [Errno 12] Cannot allocate memory

Threading a faker inside a flask app

I have a flask app with websockets, and when a person hits a socket to start threading, I want it to run a thread like:
#socketio.on('start', namespace='/ws')
def patrol():
asset = {'x': 0, 'y': 1}
while True:
thread_patrol(asset, [[0, 0], [400, 400]])
def patrol(asset, coordinates):
count = 0
import itertools
for coordinate in itertools.cycle(coordinates):
val = True
while val:
asset, val = take_step(asset, coordinate[0], coordinate[1])
emit('asset',
{'data': asset, 'count': count},
broadcast=True)
count += 1
time.sleep(1)
import threading
def thread_patrol(asset, coordinates):
print('threading!')
patrolling_thread = threading.Thread(target=patrol, args=(asset, coordinates))
patrolling_thread.start()
def take_step(asset, x, y):
asset[x] = x
asset[y] = y
But then I get an error because it's outside of request context. What do I need to do to allow my app to thread?:
threading!
Exception in thread Thread-2005:
Traceback (most recent call last):
File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "app2.py", line 270, in patrol
broadcast=True)
File "/usr/local/lib/python2.7/site-packages/flask_socketio/__init__.py", line 520, in emit
namespace = flask.request.namespace
File "/usr/local/lib/python2.7/site-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/usr/local/lib/python2.7/site-packages/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/usr/local/lib/python2.7/site-packages/flask/globals.py", line 20, in _lookup_req_object
raise RuntimeError('working outside of request context')
RuntimeError: working outside of request context
You (I) have to include thread.daemon = True to inform the app to run it as a background process, and I removed broadcast=True since that wasn't necessary anyways.
def thread_patrol(asset, coordinates):
patrolling_thread = Thread(target=patrol, args=(asset, coordinates))
thread.daemon = True
thread.start()

threading.Timer TypeError: an integer is required

I'm trying to write script which execute something after double click CTRL. It works well after first double click, but then I get that error. Also if I press CTRL once and again after timer execute function trigger I'll get same error.
import pythoncom, pyHook, threading
press = False
def triger():
global press
press=False
def something():
print 'hello'
def OnKeyboardEvent(event):
global press
if event.Key=='Lcontrol':
if press:
something()
press = False
else:
press=True
threading.Timer(1,triger).start()
hm = pyHook.HookManager()
hm.KeyDown = OnKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages()
Error:
hello
Warning (from warnings module):
File "C:\Python27\lib\threading.py", line 828
return _active[_get_ident()]
RuntimeWarning: tp_compare didn't return -1 or -2 for exception
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\pyHook\HookManager.py", line 351, in KeyboardSwitch
return func(event)
File "C:\Users\123\Desktop\code\hooks.py", line 20, in OnKeyboardEvent
threading.Timer(1,triger).start()
File "C:\Python27\lib\threading.py", line 731, in Timer
return _Timer(*args, **kwargs)
File "C:\Python27\lib\threading.py", line 742, in __init__
Thread.__init__(self)
File "C:\Python27\lib\threading.py", line 446, in __init__
self.__daemonic = self._set_daemon()
File "C:\Python27\lib\threading.py", line 470, in _set_daemon
return current_thread().daemon
File "C:\Python27\lib\threading.py", line 828, in currentThread
return _active[_get_ident()]
TypeError: an integer is required
Acording to the documentation there have to be "return True" at the end of OnKeyboardEvent function. Here's how it looks like.
def OnKeyboardEvent(event):
global press
if event.Key=='Lcontrol':
if press:
something()
press = False
else:
press=True
threading.Timer(1,triger).start()
print 'waiting'
return True

Categories