Last updated: Apr 11, 2024
Reading time·2 min

The Python "TypeError: cannot pickle '_thread.lock' object" occurs when you
try to pickle a _thread.lock object.
To solve the error, remove the _thread.lock object before pickling.
Here is an example of how the error occurs.
import pickle import threading a_dict = { 'website': 'bobbyhadz.com', 'topic': 'Python', 'lock_object': threading.Lock() } # ⛔️ TypeError: cannot pickle '_thread.lock' object with open('example.pickle', 'wb') as file_handle: pickle.dump(a_dict, file_handle, protocol=pickle.HIGHEST_PROTOCOL)

Notice that the dictionary contains a key that points to a lock object.
Pickling a lock object is not allowed and so the error is raised.
The
threading.Lock
class is used to create lock objects.
Once a thread has acquired a lock, subsequent attempts to acquire it block until it is released.
lock object before picklingOne way to solve the error is to remove the lock object before pickling.
import pickle import threading a_dict = { 'website': 'bobbyhadz.com', 'topic': 'Python', 'lock_object': threading.Lock() } del a_dict['lock_object'] with open('example.pickle', 'wb') as file_handle: pickle.dump(a_dict, file_handle, protocol=pickle.HIGHEST_PROTOCOL)

The code sample uses the
del
statement to remove the lock_object key from the dictionary.
You might also have gotten the error when storing a lock object in a list.
import pickle import threading a_list = ['bobby', 'hadz', 'com', threading.Lock()] # ⛔️ TypeError: cannot pickle '_thread.lock' object with open('example.pickle', 'wb') as file_handle: pickle.dump(a_list, file_handle, protocol=pickle.HIGHEST_PROTOCOL)
You can iterate over the list and remove all lock objects before pickling.
import pickle import threading a_list = ['bobby', 'hadz', 'com', threading.Lock()] for item in a_list.copy(): if hasattr(item, 'release') and hasattr(item, 'locked'): a_list.remove(item) with open('example.pickle', 'wb') as file_handle: pickle.dump(a_list, file_handle, protocol=pickle.HIGHEST_PROTOCOL)
We used a for loop to iterate over a copy of the list.
Iterating over a copy is necessary because you aren't allowed to remove items from a list while iterating over it.
On each iteration, we check if the current item is a lock object.
If the condition is met, we remove the lock object from the list.
__getstate__ in a classYou can also remove the lock object using a custom class.
import pickle import threading class Pickler: def __init__(self): self.website = 'bobbyhadz.com' self.topic = 'Python' self.lock_object = threading.Lock() def __getstate__(self): state = self.__dict__.copy() print(state) # 👇️ don't pickle the lock_object key del state['lock_object'] return state obj1 = Pickler() print(obj1) with open('example.pickle', 'wb') as file_handle: pickle.dump(obj1, file_handle, protocol=pickle.HIGHEST_PROTOCOL) print('success')

The object.__getstate__ method can be used to influence how instances are pickled.
The method is called and the returned object is pickled as the contents for the instance, instead of a default state.
You can learn more about the related topics by checking out the following tutorials: