Frozenset: `fs.copy()` and frozenset(fs) returns fs. Is it intended?

Reading the C source code of frozenset, I discovered that:

>>> fs = frozenset((0, ))
>>> fs is frozenset(fs)
True
>>> fs is fs.copy()
True
>>> import copy
>>> copy.copy(fs) is fs
True

This is true for all immutable types. For example, mytuple is mytuple[:]. I think this is useful, but it’s a bit confusing for copy(). Honestly I expect that it will return a new equal object, not the old one.
To have a new object, you must do copy.deepcopy(fs) or frozenset(set(fs)).

I think it should be at least documented as CPython implementation detail.

We shouldn’t because then we are beholden to keeping those semantics. Consider these sematnics accidental.

1 Like

Well, even if it’s accidental, IMHO a Python coder is interested to know it. Maybe (s)he really needs to copy an immutable to another object, and this can cause subtle bugs in his/her code.

PS: semantics?

It’s not actually accidental, we just don’t want people relying on it explicitly.

That’s fine, but that doesn’t mean it needs to be documented and thus something we need to support forever.

The whole point of immutable objects is that’s not necessary, hence the design. You will need to provide an actual need for this for us to consider it a motivation.

2 Likes