On Thu, 22 Dec 2022 at 04:14, Christopher Barker <[email protected]> wrote:
>
> On Wed, Dec 21, 2022 at 8:54 AM Chris Angelico <[email protected]> wrote:
>>
>> > I think both of those will call self.__str__, which creates a recursion --
>> > that's what I'm trying to avoid.
>> >
>> > I'm sure there are ways to optimize this -- but only worth doing if it's
>> > worth doing at all :-)
>> >
>>
>> Second one doesn't seem to.
>>
>> >>> class Str(str):
>> ... def __str__(self):
>> ... print("str!")
>> ... return "spam"
>> ... def __repr__(self):
>> ... print("repr!")
>> ... return "SPAM"
>> ...
>> >>> s = Str("ham")
>> >>> f"{s}"
>> str!
>> 'spam'
>> >>> "".join((s,))
>> 'ham'
>
>
> hmm -- interesting trick -- I had jumped to that conclusion -- I wonder what
> it IS using under the hood?
>
>From the look of things, PyUnicode_Join (the internal function that
handles str.join()) uses a lot of "reaching into the data structure"
operations for efficiency. It uses PyUnicode_Check (aka "isinstance(x,
str)") rather than PyUnicode_CheckExact (aka "type(x) is str") and
then proceeds to cast the pointer and directly inspect its members.
As such, I don't think UserString can ever truly be a str, and it'll
never work with str.join(). The best you'd ever get would be
explicitly mapping str over everything first:
>>> s2 = UserString("eggs")
>>> "-".join(str(s) for s in [s, s2])
str!
'spam-eggs'
And we don't want that to be the default, since we're not writing
JavaScript code here.
ChrisA
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/3K36PWE26GVKNH5IFV44D6VKRO6TLBGB/
Code of Conduct: http://python.org/psf/codeofconduct/