Skip to content

builtins.set __sizeof__ changes after copying #107175

@KristinnVikar

Description

@KristinnVikar

Bug report

At some lengths, calling __sizeof__() on a set gives a different value after copying said set.
The inconsistency shows up as both an increase or a decrease in reported size.
Any copying of the set results in this behavior, but modifying the set itself does not.

I've tested looking at the memory usage of a python process with regard to the created set, and it looks like the copied set has the correct __sizeof__ value.

Simple repro:

import sys

a = set(range(10_000_000))
b = a.copy()
c = set(a)
d = a.union({1})

print(a == b == c)  # -> True

print(sys.getsizeof(a))  # -> 268435672
print(sys.getsizeof(b))  # -> 536871128
print(sys.getsizeof(c))  # -> 536871128
print(sys.getsizeof(d))  # -> 536871128

print(a.__sizeof__())  # -> 268435656
print(b.__sizeof__())  # -> 536871112
print(c.__sizeof__())  # -> 536871112
print(d.__sizeof__())  # -> 536871112

But at other lengths, the reported size is the same.

import sys

a = set(range(10_000))
b = a.copy()
c = set(a)

print(a == b == c)  # -> True

print(sys.getsizeof(a))  # -> 524504
print(sys.getsizeof(b))  # -> 524504
print(sys.getsizeof(c))  # -> 524504

print(a.__sizeof__())  # -> 524488
print(b.__sizeof__())  # -> 524488
print(c.__sizeof__())  # -> 524488

I made a quick script to find the sizes this inconsistency applies to. And testing seems to show that 43.7% of all lengths below 50,000 have this issue.

for i in range(500):
    a = set(range(i))
    b = a.copy()
    assert a == b

    if a.__sizeof__() != b.__sizeof__():
        print(f"{i}: True")
    else:
        print(f"{i}: False")

My expectation is that the reported size would not change from copying a set.

Your environment

Tested on both Ubuntu and Debian with same results

  • CPython versions tested on:
    • 3.11.0
    • 3.11.2
  • Operating system and architecture:
    • Ubuntu 22.04.2 LTS
    • Debian GNU/Linux 12

Metadata

Metadata

Assignees

No one assigned

    Labels

    pendingThe issue will be closed if no feedback is providedtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions