[issue44356] Abstract enum mixins not allowed

2021-06-11 Thread Jordan Ephron


Jordan Ephron  added the comment:

On 10.06.2021 15:33, Ethan Furman wrote:
>Since I like puzzles, here is a working LenientStrEnum:
>...

Oh indeed, that's really cool!

--
title: Multiple enum mixins not allowed even when they have the same datatype 
-> Abstract enum mixins not allowed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44356] Abstract enum mixins not allowed

2021-06-10 Thread Ethan Furman


Ethan Furman  added the comment:

Since I like puzzles, here is a working LenientStrEnum:

class LenientStrEnum(str, Enum):
#
def __init__(self, *args):
self._valid = True
#
@classmethod
def _missing_(cls, value):
logger.warning(
f"[{cls.__name__}] encountered an unknown value!\n"
f"Luckily I'm a LenientStrEnum, so I won't crash just yet.\n"
f"You might want to add a new case though.\n"
f"Value was: '{value}'"
)
unknown = cls._member_type_.__new__(cls, value)
unknown._valid = False
unknown._name_ = value.upper()
unknown._value_ = value
cls._member_map_[value] = unknown
return unknown
#
@property
def valid(self):
return self._valid

`_member_map_` is not guaranteed, but is unlikely to change.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44356] Abstract enum mixins not allowed

2021-06-09 Thread Jordan Ephron


Jordan Ephron  added the comment:

Oh, on further investigation I see that the example wouldn't have worked on 3.8 
anyway, due to issue34536 adding some checks to the type returned by _missing_, 
so maybe I'm pushing Enum too far in that case.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44356] Abstract enum mixins not allowed

2021-06-09 Thread Jordan Ephron

Jordan Ephron  added the comment:

> But what is an `UnexpectedString()`

Sorry, that’s maybe less relevant to the example. It’s just a subclass of 
string with some marker to make it detectable later on, similar to schemes that 
taint user input to prevent sql injection or whatever

> On Jun 8, 2021, at 23:20, Ethan Furman  wrote:
> 
> 
> Ethan Furman  added the comment:
> 
> Excellent bug report.
> 
> But what is an `UnexpectedString()` ?
> 
> --
> 
> ___
> Python tracker 
> 
> ___

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44356] Abstract enum mixins not allowed

2021-06-09 Thread Ethan Furman


Ethan Furman  added the comment:

Excellent bug report.

But what is an `UnexpectedString()` ?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44356] Abstract enum mixins not allowed

2021-06-08 Thread Ethan Furman


Change by Ethan Furman :


--
assignee:  -> ethan.furman
nosy: +ethan.furman
versions: +Python 3.10, Python 3.11

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44356] Abstract enum mixins not allowed

2021-06-08 Thread Jordan Ephron


New submission from Jordan Ephron :

Prior to 3.8 it was possible to create "abstract" enums (without members) and 
mix them together. To motivate with an example, perhaps we're modeling an API 
and want to be robust in the face of inconsistent casing


class CaseInsensitiveStrEnum(str, Enum):
@classmethod
def _missing_(cls, value):
for member in cls._member_map_.values():
if member._value_.lower() == value.lower():
return member
return super()._missing_(value)


and perhaps we also want to be robust in response to extensibility


class LenientStrEnum(str, Enum):
@classmethod
def _missing_(cls, value):
logger.warning(
f"[{cls.__name__}] encountered an unknown value!\n"
f"Luckily I'm a LenientStrEnum, so I won't crash just yet.\n"
f"You might want to add a new case though.\n"
f"Value was: '{value}'"
)
return UnexpectedStr(value)


but we also want to model some known good set of values, so mixing together the 
abstract enums we'd get something like


class JobStatus(CaseInsensitiveStrEnum, LenientStrEnum):
ACTIVE = "active"
PENDING = "pending"
TERMINATED = "terminated"

However, due to the resolution of https://bugs.python.org/issue39587 this no 
longer works, instead producing:

TypeError: 'JobStatus': too many data types: [, ]


The relevant change is

https://github.com/ethanfurman/cpython/commit/bff01f3a3aac0c15fe8fbe8b2f561f7927d117a1

I believe that if we made `data_types` a set rather than a list then the 
example would become valid once again.

--
messages: 395378
nosy: JEphron
priority: normal
severity: normal
status: open
title: Abstract enum mixins not allowed
type: behavior
versions: Python 3.8, Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com