On Tue, 20 Dec 2022 at 12:55, Ethan Furman <et...@stoneleaf.us> wrote:
>
> On 12/19/22 13:59, Chris Angelico wrote:
>
>  > The way things are, a StrEnum or an HTML string will behave *exactly
>  > as a string does*. The alternative is that, if any new operations are
>  > added to strings in the future, they have to be explicitly blocked by
>  > StrEnum or else they will randomly and mysteriously misbehave - or, at
>  > very best, crash with unexpected errors. Which one is more hostile to
>  > subclasses?
>
> As Brendan noted, mixed-type enums are special -- they are meant to be 
> whatever they subclass, with a couple extra
> features/restrictions.

Fair, but defaultdict also exhibits this behaviour, so maybe there are
a number of special cases. Or, as Syndrome put it: "When everyone's
[special]... no one will be."

> Personally, every other time I've wanted to subclass a built-in data type, 
> I've wanted the built-in methods to return my
> subclass, not the original class.
>
> All of which is to say:  sometimes you want it one way, sometimes the other.  
> ;-)

Yep, sometimes each way. So the real question is not "would the
opposite decision make sense in some situations?" but "which one is
less of a problem when it's the wrong decision?". And I put it to you
that returning an instance of the base type is less of a problem, in
the same way that *any other* operation unaware of the subclass would
behave.

def underline(head):
    """Build an underline line for the given heading"""
    return "=" * len(head)

Would you expect underline() to return the same type as head, or a
plain str? Would this be true of every single function that returns
something of the same kind as one of its parameters?

> Metaclasses, anyone?

Hmm, how would they help? I do think that metaprogramming could help
here, but not sure about metaclasses specifically.

If I wanted to automate this, I'd go for something like this:

@autospecialize
class Str(str):
    def extra_method(self): ...

where the autospecialize decorator would look at your class's first
base class, figure out which methods should get this treatment (only
if not overridden, only if they return that type, not __new__, maybe
other rules), and then add a wrapper that returns __class__(self). But
people will dispute parts of that. Maybe it should be explicitly told
which base class to handle this way. Maybe it'd be better to have an
intermediate class, rather than mutating the subclass. Maybe you
should be explicit about which methods get autospecialized. It's not
an easy problem, and simply returning the base class is the one option
that you can be confident of.

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/X263X2B4VUEWJIDRL27FNYE2C3S5KV77/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to