diff --git a/Lib/copy.py b/Lib/copy.py index c64fc0761793f5..02a7b2c3b8531a 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -129,32 +129,25 @@ def deepcopy(x, memo=None, _nil=[]): copier = _deepcopy_dispatch.get(cls) if copier is not None: y = copier(x, memo) - else: - if issubclass(cls, type): + elif issubclass(cls, type): y = x # atomic copy + elif (copier := getattr(x, "__deepcopy__", None)) is not None: + y = copier(memo) + else: + if (reductor := dispatch_table.get(cls)): + rv = reductor(x) + elif (reductor := getattr(x, "__reduce_ex__", None)) is not None: + rv = reductor(4) + elif (reductor := getattr(x, "__reduce__", None)): + rv = reductor() else: - copier = getattr(x, "__deepcopy__", None) - if copier is not None: - y = copier(memo) - else: - reductor = dispatch_table.get(cls) - if reductor: - rv = reductor(x) - else: - reductor = getattr(x, "__reduce_ex__", None) - if reductor is not None: - rv = reductor(4) - else: - reductor = getattr(x, "__reduce__", None) - if reductor: - rv = reductor() - else: - raise Error( - "un(deep)copyable object of type %s" % cls) - if isinstance(rv, str): - y = x - else: - y = _reconstruct(x, memo, *rv) + raise Error( + "un(deep)copyable object of type %s" % cls) + + if isinstance(rv, str): + y = x + else: + y = _reconstruct(x, memo, *rv) # If is its own copy, don't memoize. if y is not x: diff --git a/Misc/NEWS.d/next/Library/2025-06-23-21-45-12.gh-issue-135865.3C6P4k.rst b/Misc/NEWS.d/next/Library/2025-06-23-21-45-12.gh-issue-135865.3C6P4k.rst new file mode 100644 index 00000000000000..d253561bdba44d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-23-21-45-12.gh-issue-135865.3C6P4k.rst @@ -0,0 +1 @@ +Refactor ``copy.deepcopy`` with the walrus operator.