[lang-ref] ( deep_copy ) ( python )

def test_deep_copy():
    # copy.deepcopy

    import copy

    list_original = [['A1', 'B1'], ['A2', 'B2']]
    list_shallow1 = list(list_original)
    list_shallow2 = copy.copy(list_original)
    list_deep     = copy.deepcopy(list_original)

    assert list_shallow1[0][0] == list_original[0][0]
    assert list_shallow1[0][1] == list_original[0][1]
    assert list_shallow1[1][0] == list_original[1][0]
    assert list_shallow1[1][1] == list_original[1][1]

    assert list_shallow2[0][0] == list_original[0][0]
    assert list_shallow2[0][1] == list_original[0][1]
    assert list_shallow2[1][0] == list_original[1][0]
    assert list_shallow2[1][1] == list_original[1][1]

    assert list_deep[0][0] == list_original[0][0]
    assert list_deep[0][1] == list_original[0][1]
    assert list_deep[1][0] == list_original[1][0]
    assert list_deep[1][1] == list_original[1][1]

    # object is distinct
    assert list_shallow1 is not list_original
    assert list_shallow2 is not list_original
    assert list_deep     is not list_original

    # top elements are references in shallow copy
    assert list_shallow1[0] is     list_original[0]
    assert list_shallow1[1] is     list_original[1]
    assert list_shallow2[0] is     list_original[0]
    assert list_shallow2[1] is     list_original[1]
    assert list_deep[0]     is not list_original[0]
    assert list_deep[1]     is not list_original[1]

    # modify original
    list_original[0]    = ['A1-mod', 'B1-mod']  # does not affect the copies (rebinds the inner list)
    list_original[1][1] = 'B2-mod'              # affects shallow copies (mutates a shared inner list)

    assert list_shallow1[0][0] == 'A1'
    assert list_shallow1[0][1] == 'B1'
    assert list_shallow1[1][0] == 'A2'
    assert list_shallow1[1][1] == 'B2-mod'

    assert list_shallow2[0][0] == 'A1'
    assert list_shallow2[0][1] == 'B1'
    assert list_shallow2[1][0] == 'A2'
    assert list_shallow2[1][1] == 'B2-mod'

    assert list_deep[0][0] == 'A1'
    assert list_deep[0][1] == 'B1'
    assert list_deep[1][0] == 'A2'
    assert list_deep[1][1] == 'B2'