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.

InheritsBaseException›Exception›Error
copy exceptionAll Python versions
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
True
4. 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' object

Pitfalls

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.