copy.Error
copy.copy and copy.deepcopy raise copy.Error only when an object has no __copy__/__deepcopy__, no copyreg entry, and both __reduce_ex__ and __reduce__ are missing or None. Everyday failures — modules, locks, files, generators — come from the pickle protocol as TypeError.
copy.Error
Raised by
copy.copy(obj), copy.deepcopy(obj) when obj disables every copy hook
Message
un(shallow)copyable object of type <class '...'>
Quick fix
Give the class __copy__ / __deepcopy__, or stop setting __reduce_ex__ to None
Watch out
Catch TypeError too: that is what most uncopyable objects raise
Common patterns
Copy if possible
Fall back to sharing the object when it cannot be copied.
import copy try: value = copy.deepcopy(value) except (copy.Error, TypeError): pass # keep the shared reference
Forbid copying on purpose
Raise a clear error from the hooks instead of relying on copy.Error.
class Connection: def __copy__(self): raise TypeError("Connection objects cannot be copied") __deepcopy__ = lambda self, memo: self.__copy__()
Examples
1. Shallow copy of a class with no hooks
import copy
class Sealed:
__reduce_ex__ = None
__reduce__ = None
copy.copy(Sealed())
Returns
copy.Error: un(shallow)copyable object of type <class '__main__.Sealed'>2. Deep copy says "deep"
import copy
class Sealed:
__reduce_ex__ = None
__reduce__ = None
copy.deepcopy(Sealed())
Returns
copy.Error: un(deep)copyable object of type <class '__main__.Sealed'>3. copy.error is the same class
import copy
copy.error is copy.Error
Returns
True4. It is a plain Exception subclass
import copy
copy.Error.__mro__
Returns
(<class 'copy.Error'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>)5. Modules raise TypeError, not copy.Error
import copy, math
copy.deepcopy(math)
Returns
TypeError: cannot pickle 'module' objectPitfalls
1. Catching only copy.Error
Locks, files, generators and modules fail inside the pickle protocol with TypeError, which except copy.Error does not catch.
except copy.Error
import copy, threading try: copy.deepcopy(threading.Lock()) except copy.Error: result = 'not copyable' result
TypeError: cannot pickle '_thread.lock' object
except (copy.Error, TypeError)
import copy, threading try: copy.deepcopy(threading.Lock()) except (copy.Error, TypeError): result = 'not copyable' result
'not copyable'
When to use
Use it
- Catching it together with TypeError around copy/deepcopy of arbitrary objects
Reach for something else
- Raising it from your own code → raise TypeError with a clear message
Notes
CPython impl
class Error(Exception) in Lib/copy.py, with error = Error kept as a backward-compatible alias; raised at the end of the __reduce_ex__ / __reduce__ fallback chain
Message
"un(shallow)copyable object of type %s" from copy(), "un(deep)copyable object of type %s" from deepcopy(), formatted with the class
FAQ
Only when copy() or deepcopy() finds no copy mechanism at all: no __copy__/__deepcopy__, no copyreg registration, and __reduce_ex__ and __reduce__ both missing or None. Normal classes always inherit __reduce_ex__ from object, so in practice this is rare.