The Secret Life of Python - The Uncopyable (deepcopy)
Source: Dev.to
When deepcopy fails: why some Python objects can’t be cloned
Audio edition: AI podcast on YouTube
Video edition: 7‑minute visual explainer on YouTube
The story
Timothy thought he had mastered Python’s deepcopy. He tried to back up his tournament database by deep‑copying the entire Connection object.
“I deep‑copied the database connection,” he told Margaret.
“But Python just… exploded.”
The traceback ended with:
TypeError: cannot pickle '_thread.lock' object
Why deepcopy mentions pickling
deepcopy works by pickling an object internally – converting it to a byte stream and then reconstructing it. This works for pure data structures, but it fails for objects that represent live resources (e.g., file handles, sockets, thread locks). Those resources are tied to the operating system and cannot be serialized into a portable byte stream.
A database connection, a file handle, or a network socket isn’t just data; it’s a live link to something outside of Python.
Data vs. Resources
| Category | Examples | deepcopy outcome |
|---|---|---|
| Pure Data | Lists, dicts, custom info classes | ✅ Works |
| Resources | Files, DB connections, sockets, thread locks | ❌ Fails |
The right way: use a Builder/Factory
Instead of cloning the live object, recreate it from its configuration.
# The WRONG way (crashes)
# backup_conn = copy.deepcopy(original_conn)
# The RIGHT way (Builder)
def create_connection(config):
"""Create a fresh database connection from a config dict."""
return database.connect(config)
db_config = {"host": "localhost", "user": "admin"}
conn1 = create_connection(db_config)
conn2 = create_connection(db_config)
“You copy the config (the map), not the connection (the journey).”
High‑level warning
Is it pure Data? →
deepcopyworks.
Is it a Resource? →deepcopyfails; use a builder/factory.
Advanced note
Objects can define their own __deepcopy__ method to handle custom copying logic, but for system resources it is almost always safer to create a fresh instance rather than trying to clone the existing one.
Takeaway
Even the “ultimate” cloning tool has limits. The best engineers choose the right tool for the material they’re working with.
Next episode teaser: Margaret and Timothy will explore “The Default Trap” – why giving a function a mutable default argument (like a list) is a bad idea.