Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-134559: Expand and reorganise documentation for the copy module #134695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 58 additions & 30 deletions Doc/library/copy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ Assignment statements in Python do not copy objects, they create bindings
between a target and an object. For collections that are mutable or contain
mutable items, a copy is sometimes needed so one can change one copy without
changing the other. This module provides generic shallow and deep copy
operations (explained below).
operations (explained below), plus a replace (copy-with-modifications)
operation that's implemented for certain immutable types.


Interface summary:
``copy`` and ``deepcopy``
-------------------------
Comment on lines +19 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
``copy`` and ``deepcopy``
-------------------------
:func:`!copy()` and :func:`!deepcopy()`
---------------------------------------


.. function:: copy(obj)

Expand All @@ -27,28 +29,18 @@ Interface summary:
Return a deep copy of *obj*.


.. function:: replace(obj, /, **changes)

Creates a new object of the same type as *obj*, replacing fields with values
from *changes*.

.. versionadded:: 3.13


.. exception:: Error

Raised for module specific errors.

.. _shallow_vs_deep_copy:

The difference between shallow and deep copying is only relevant for compound
objects (objects that contain other objects, like lists or class instances):
.. tip:: Shallow vs. Deep Copy

The difference between shallow and deep copying is only relevant for compound
objects (objects that contain other objects, like lists or class instances):
Comment on lines +36 to +37
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'container' is more commonly used and the name of a collections ABC

Suggested change
The difference between shallow and deep copying is only relevant for compound
objects (objects that contain other objects, like lists or class instances):
The difference between shallow and deep copying is only relevant for container
objects; those that contain other objects, like lists or class instances:


* A *shallow copy* constructs a new compound object and then (to the extent
possible) inserts *references* into it to the objects found in the original.
* A *shallow copy* constructs a new compound object and then (to the extent
possible) inserts *references* into it to the objects found in the original.

* A *deep copy* constructs a new compound object and then, recursively, inserts
*copies* into it of the objects found in the original.
* A *deep copy* constructs a new compound object and then, recursively,
inserts *copies* into it of the objects found in the original.

Two problems often exist with deep copy operations that don't exist with shallow
copy operations:
Expand Down Expand Up @@ -76,13 +68,27 @@ Shallow copies of dictionaries can be made using :meth:`dict.copy`, and
of lists by assigning a slice of the entire list, for example,
``copied_list = original_list[:]``.


Pickling
~~~~~~~~

.. index:: pair: module; pickle

Classes can use the same interfaces to control copying that they use to control
pickling. See the description of module :mod:`pickle` for information on these
methods. In fact, the :mod:`copy` module uses the registered
pickle functions from the :mod:`copyreg` module.

.. seealso::

Module :mod:`pickle`
Discussion of the special methods used to support object state retrieval and
restoration.


The copy protocol
~~~~~~~~~~~~~~~~~

.. index::
single: __copy__() (copy protocol)
single: __deepcopy__() (copy protocol)
Expand All @@ -103,29 +109,51 @@ special methods :meth:`~object.__copy__` and :meth:`~object.__deepcopy__`.

Called to implement the deep copy operation; it is passed one
argument, the *memo* dictionary. If the ``__deepcopy__`` implementation needs
to make a deep copy of a component, it should call the :func:`~copy.deepcopy` function
to make a deep copy of a component, it should call the :func:`!copy.deepcopy` function
with the component as first argument and the *memo* dictionary as second argument.
The *memo* dictionary should be treated as an opaque object.


``replace``
-----------
Comment on lines +117 to +118
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
``replace``
-----------
:func:`!replace()`
------------------


.. function:: copy.replace(obj, /, **changes)

Return a new object of the same type as *obj*, replacing fields with values
from *changes*.

Function :func:`!copy.replace` is more limited
than :func:`~copy.copy` and :func:`~copy.deepcopy`,
and only supports named tuples created by :func:`~collections.namedtuple`,
:mod:`dataclasses`, and other classes which implement the replace protocol
(i.e. define a method :meth:`~object.__replace__`).
Comment on lines +125 to +129
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Function :func:`!copy.replace` is more limited
than :func:`~copy.copy` and :func:`~copy.deepcopy`,
and only supports named tuples created by :func:`~collections.namedtuple`,
:mod:`dataclasses`, and other classes which implement the replace protocol
(i.e. define a method :meth:`~object.__replace__`).
The :func:`!replace` function is more limited than
:func:`~copy.copy` and :func:`~copy.deepcopy`.
For example, it only supports named tuples created by :func:`~collections.namedtuple`,
:mod:`dataclasses`, and other classes which implement the replace protocol
(i.e. those defining a :meth:`~object.__replace__` method).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(i.e. define a method :meth:`~object.__replace__`).
(that is, those defining a :meth:`~object.__replace__` method).


.. versionadded:: 3.13


The replace protocol
~~~~~~~~~~~~~~~~~~~~

.. index::
single: __replace__() (replace protocol)

Function :func:`!copy.replace` is more limited
than :func:`~copy.copy` and :func:`~copy.deepcopy`,
and only supports named tuples created by :func:`~collections.namedtuple`,
:mod:`dataclasses`, and other classes which define method :meth:`~object.__replace__`.
In order for a class to define its own replace implementation, it can define
the special method :meth:`~object.__replace__`.


.. method:: object.__replace__(self, /, **changes)
:noindexentry:

This method should create a new object of the same type,
Called to implement the replace operation; it is passed a set of changes
as keyword arguments. This method should create a new object of the same type,
replacing fields with values from *changes*.

.. versionadded:: 3.13

.. seealso::

Module :mod:`pickle`
Discussion of the special methods used to support object state retrieval and
restoration.
Exceptions
----------

.. exception:: copy.Error

Raised for module specific errors.
Loading