
On Mon, Jan 17, 2022 at 9:55 AM Steven D'Aprano <steve@pearwood.info> wrote:
On Sun, Jan 16, 2022 at 04:50:40PM +0000, MRAB wrote:
Not quite as bad as that:
f = frozenset({1, 2, 3}) f is frozenset(f) True
Mark suggested that on the bug tracker too, but that's not relevant. As I replied there:
def f(): ... return frozenset({1, 2, 3}) ... a = f.__code__.co_consts[1] a frozenset({1, 2, 3}) b = f() assert a == b a is b False
Each time you call the function, you get a distinct frozenset object.
And semantically, I believe that's correct. The set display MUST create a new set every time, and since the compiler/optimizer can't assume that the name 'frozenset' hasn't been rebound, it has to then call the function to get its result. So it will, by language definition, build a set from the given values, then build a frozenset from that. It optimizes "add 1, add 2, add 3" down to "here's a frozenset, add them", but it can't skip the whole job. def frozenset(stuff): print("You can't optimize me out") stuff.remove(2) return builtins.frozenset(stuff) If the compiler did any of the optimizations it's currently not doing, this code would break. The only way to solve this is an actual frozenset literal, and I would love to have one, but it stands or falls on the syntax. ChrisA