@property
    def data(self):
        return f"{self}"

Not at a workstation but this should be faster than join() while still
using syntax and not builtin functions.


~ Jeremiah

On Tue, Dec 20, 2022 at 5:38 PM Christopher Barker <python...@gmail.com>
wrote:

> As has been said, a builtin *could* be written that would be "friendly to
> subclassing", by the definition in this thread. (I'll stay out of the
> argument for the moment as to whether that would be better)
>
> I suspect that the reason str acts like it does is that it was originally
> written a LONG time ago, when you couldn't subclass basic built in types at
> all.
>
> Secondarily, it could be a performance tweak -- minimal memory and peak
> performance are pretty critical for strings.
>
> But collections.UserString does exist -- so if you want to subclass, and
> performance isn't critical, then use that. Steven A pointed out that
> UserStrings are not instances of str though. I think THAT is a bug. And
> it's probably that way because with the magic of duck typing, no one cared
> -- but with all the static type hinting going on now, that is a bigger
> liability than it used to be. Also basue when it was written, you couldn't
> subclass str.
>
> Though I will note that run-time type checking of string is relatively
> common compared to other types, due to the whole a-str-is-a-sequence-of-str
> issue making the distinction between a sequence of strings and a string
> itself is sometimes needed. And str is rarely duck typed.
>
> If anyone actually has a real need for this I'd post an issue -- it'd be
> interesting if the core devs see this as a bug or a feature (well, probably
> not feature, but maybe missing feature)
>
> OK -- I got distracted and tried it out -- it was pretty easy to update
> UserString to be a subclass of str. I suspect it isn't done that way now
> because it was originally written because you could not subclass str -- so
> it stored an internal str instead.
>
> The really hacky part of my prototype is this:
>
> # self.data is the original attribute for storing the string internally.
> Partly to prevent my having to re-write all the other methods, and partly
> because you get recursion if you try to use the methods on self when
> overriding them ...
>
>     @property
>     def data(self):
>         return "".join(self)
>
> The "".join is because it was the only way I quickly thought of to make a
> native string without invoking the __str__ method and other initialization
> machinery. I wonder if there is another way? Certainly there is in C, but
> in pure Python?
>
> Anyway, after I did that and wrote a __new__ -- the rest of it "just
> worked".
>
>     def __new__(cls, s):
>         return super().__new__(cls, s)
>
> UserString and its subclasses return instances of themselves, and
> instances are instances of str.
>
> Code with a couple asserts in the __main__ block enclosed.
>
> Enjoy!
>
> -CHB
>
> NOTE: VERY minimally tested :-)
>
> On Tue, Dec 20, 2022 at 4:17 PM Chris Angelico <ros...@gmail.com> wrote:
>
>> On Wed, 21 Dec 2022 at 09:30, Cameron Simpson <c...@cskk.id.au> wrote:
>> >
>> > On 19Dec2022 22:45, Chris Angelico <ros...@gmail.com> wrote:
>> > >On Mon, 19 Dec 2022 at 22:37, Steven D'Aprano <st...@pearwood.info>
>> wrote:
>> > >> > But this much (say with a better validator) gets you static type
>> checking,
>> > >> > syntax highlighting, and inherent documentation of intent.
>> > >>
>> > >> Any half-way decent static type-checker will immediately fail as
>> soon as
>> > >> you call a method on this html string, because it will know that the
>> > >> method returns a vanilla string, not a html string.
>> > >
>> > >But what does it even mean to uppercase an HTML string? Unless you
>> > >define that operation specifically, the most logical meaning is
>> > >"convert it into a plain string, and uppercase that".
>> >
>> > Yes, this was my thought. I've got a few subclasses of builtin types.
>> > They are not painless.
>> >
>> > For HTML "uppercase" is a kind of ok notion because the tags are case
>> > insensitive.
>>
>> Tag names are, but their attributes might not be, so even that might
>> not be safe.
>>
>> > Notthe case with, say, XML - my personal nagging example is
>> > from KML (Google map markup dialect) where IIRC a "ScreenOverlay" and a
>> > "screenoverlay" both existing with different semantics. Ugh.
>>
>> Ugh indeed. Why? Why? Why?
>>
>> > So indeed, I'd probably _want_ .upper to return a plain string and have
>> > special methods to do more targetted things as appropriate.
>> >
>>
>> Agreed.
>>
>> ChrisA
>> _______________________________________________
>> Python-ideas mailing list -- python-ideas@python.org
>> To unsubscribe send an email to python-ideas-le...@python.org
>> https://mail.python.org/mailman3/lists/python-ideas.python.org/
>> Message archived at
>> https://mail.python.org/archives/list/python-ideas@python.org/message/T7FZ3FIA6INMHQIRVZ3ZZJC6UAQQCFOI/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
>
> --
> Christopher Barker, PhD (Chris)
>
> Python Language Consulting
>   - Teaching
>   - Scientific Software Development
>   - Desktop GUI and Web Development
>   - wxPython, numpy, scipy, Cython
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/I62E7PVP5NN3KYYKFOW5OUKJRQSKNL4T/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/C3VIGTJTNRLUQOMB52OFPZJKYWN54WZN/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to