Reputation: 41198
Why is sys.intern() failing to intern this string?
>>> from sys import intern
>>> "abcd"[:-1] == "abc"
True
>>> "abcd"[:-1] is "abc"
False
>>> intern("abc")
'abc'
>>> "abcd"[:-1] is "abc"
False # Expected True
(on CPython 3.7.4)
Upvotes: 2
Views: 110
Reputation: 34367
Your expectations are wrong. Names, string-constants and similar are interned when the code-object is created (here) and not when any string-object is created.
The string for "abcd"[:-1]
is created during the run time and thus not interned. Theoretically, if optimizer would evaluate this expression during the compile time, it could be interned, as it happens for example with
>>> "a"*5 is "aaaaa" #True
But it is just an impelementation detail, for example
>>> "a"*4097
would no longer be evaluated during the compile time and thus not interned.
Upvotes: 0
Reputation: 36043
String literals are already interned, it's computed expressions that you'd need to intern manually.
from sys import intern
print("abcd"[:-1] is "abc") # False
print(intern("abcd"[:-1]) is "abc") # True
print("abcd"[:-1] is "abc") # False
intern
doesn't mean 'whenever this string gets produced anywhere in the program change it to the interned reference', it just returns the interned reference for the string it's given.
s1 = "abc"
s2 = "abc"
s3 = "abcd"[:-1]
s4 = intern(s3)
for s in [s1, s2, s3, s4]:
print(id(s))
140002991598512
140002991598512
140002990838576
140002991598512
Upvotes: 3