Python pickle error: cannot pickle object (tested)
TypeError: cannot pickle '_thread.lock' object, PicklingError: Can't pickle <function <lambda>> and Can't get local object all mean pickle met something it can only store by name or not at all. We measured each on Python 3.13.5.
1. What can't be pickled, and the three different exceptions you get
import pickle, threading
def make(): return lambda x: x
items = {"lambda": lambda x: x, "nested lambda": make(), "lock": threading.Lock(),
"open file": open(__file__), "generator": (i for i in range(3))}
for label, obj in items.items():
try:
pickle.dumps(obj)
except Exception as e:
print(f"{label:14} {type(e).__name__}: {e}")
Output:
lambda PicklingError: Can't pickle <function <lambda> at 0x7fa33bd92200>: attribute lookup <lambda> on __main__ failed
nested lambda AttributeError: Can't get local object 'make.<locals>.<lambda>'
lock TypeError: cannot pickle '_thread.lock' object
open file TypeError: cannot pickle 'TextIOWrapper' instances
generator TypeError: cannot pickle 'generator' object
Measured on Python 3.13.5: pickle stores functions by name, so a lambda (no usable name) fails with PicklingError, while a function defined inside another function fails with AttributeError: Can't get local object. Objects tied to the running process (locks, open files, generators, sockets, database connections) raise TypeError: cannot pickle '...'. Because these are three unrelated exception types, except pickle.PicklingError alone catches only the first one. Catch (pickle.PicklingError, TypeError, AttributeError) if you need to handle all of them.
2. Fix: drop the unpicklable attribute in __getstate__, rebuild it in __setstate__
import pickle, threading
class Worker:
def __init__(self):
self.count = 3
self.lock = threading.Lock()
def __getstate__(self):
state = self.__dict__.copy()
del state["lock"] # drop what can't be pickled
return state
def __setstate__(self, state):
self.__dict__.update(state)
self.lock = threading.Lock() # rebuild it on load
w = pickle.loads(pickle.dumps(Worker()))
print(w.count, type(w.lock).__name__)
Output:
3 lock
Measured: the object pickles and loads with its data (count = 3) and a fresh lock. Use the same pattern for open files (store the path, reopen on load) and connections (store the settings, reconnect). For functions, use a normal module-level def instead of a lambda or nested function, or functools.partial of one. With multiprocessing, the same errors appear when you pass these objects to a pool; see our multiprocessing can't pickle guide. To find which attribute is the problem, try pickle.dumps() on each value in obj.__dict__.
Frequently asked questions
Why do I get TypeError: cannot pickle '_thread.lock' object?
Your object (or something it references) holds a threading.Lock, which belongs to the running process. We measured the error and a fix: remove the lock in __getstate__ and create a new one in __setstate__.
Why can't Python pickle a lambda?
pickle stores functions by their importable name, and a lambda doesn't have one. We measured PicklingError for a module-level lambda and AttributeError: Can't get local object for a nested one.
Does except pickle.PicklingError catch all pickle errors?
No. We measured three different exception types: PicklingError, AttributeError and TypeError.
What objects cannot be pickled in Python?
We measured lambdas, nested functions, locks, open files and generators failing. Sockets and database connections behave the same way: they are tied to the running process.
Written with AI assistance. Measured on 2026-10-09 with Python 3.13.5: pickle.dumps on a lambda, a nested lambda, a threading.Lock, an open file and a generator, and a __getstate__/__setstate__ fix for a class holding a lock. Every block was run verbatim and its output pasted from that run. PlainHeaders is our extension; everything else here is built-in Python.