Andrew Barnert wrote:
> On Oct 20, 2019, at 03:36, Steve Jorgensen [email protected] wrote:
> And there are multiple PyPI projects that build Django choices on top of
> Enum, which
> show that the only thing you need is to override __getitem__ to replace its
> mapping
> behavior with sequence behavior. I believe this was also one of the examples
> of what you
> can build for yourself on top of EnumMeta in Nick Coghlan’s blog post
> explaining the
> design of enum.
> Maybe the additional functionality in Enum gets in your way for some reason I
> don’t
> understand, that doesn’t affect other people who want Django choices. But
> otherwise, I
> don’t see how it really is any different.
> And again, none of this different-from-Enum behavior is relevant to your
> problem
> anyway. The fact that you think it is, and think it can’t be done with Enum,
> makes it
> harder to understand where the actual problem is. Maybe you’re not just
> trying to do the
> same magic that all the autoenum/simplenum/etc. packages on PyPI and the PoC
> code from the
> PEP and the section in Nick’s blog post all do (in a couple different ways),
> or maybe it’s
> insufficiently magic for your purposes, but without knowing how and why it’s
> different or
> insufficient it’s impossible to know whether there’s an actual limitation to
> fix in
> Python, or just a problem in your design or implementation that could be
> easily fixed to
> work in existing Python.
So… You're exactly right. I just had a very limited understanding of what enum
was about and had not dug into it deeply enough to find out how flexible it
really is.
Here's an implementation that I came up with in a short hacking session using
enum.
Tests:
from choices import ChoiceEnum, Label as L
def test_creates_auto_valued_auto_labeled_choices():
class Food(ChoiceEnum):
APPLE = ()
ICED_TEA = ()
assert tuple(tuple(fc) for fc in Food) == (
('APPLE', 'Apple'),
('ICED_TEA', 'Iced Tea'),
)
def test_creates_auto_labeled_choices_with_given_values():
class Food(ChoiceEnum):
APPLE = 1
ICED_TEA = 2
assert tuple(tuple(fc) for fc in Food) == (
(1, 'Apple'),
(2, 'Iced Tea'),
)
def test_creates_choices_with_given_values_and_labels():
class Food(ChoiceEnum):
CHICKEN_MCNUGGETS = (1, 'Chicken McNuggets')
CHICKEN_PROVENCAL = (2, 'Chicken Provençal')
assert tuple(tuple(fc) for fc in Food) == (
(1, 'Chicken McNuggets'),
(2, 'Chicken Provençal'),
)
def test_creates_auto_valued_choices_with_given_values():
class Food(ChoiceEnum):
CHX_MN = L('Chicken McNuggets')
CHX_PV = L('Chicken Provençal')
assert tuple(tuple(fc) for fc in Food) == (
('CHX_MN', 'Chicken McNuggets'),
('CHX_PV', 'Chicken Provençal'),
)
Implementation:
from enum import Enum
class ChoiceEnum(Enum):
def __init__(self, src=None, label=None):
super().__init__()
if isinstance(src, Label):
value = None
label = str(src)
else:
value = src
self._value_ = self.name if value is None else value
self.label = label or _label_from_name(self.name)
def __getitem__(self, idx):
if idx == 0:
return self.value
elif idx == 1:
return self.label
else:
raise IndexError('Index value must be 0 or 1')
def __len__(self):
return 2
class Label(str):
pass
def _label_from_name(name):
return name.replace('_', ' ').title()
_______________________________________________
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/SPSAC7RF2W5IYZ2F45MIAUHSWJMXGAQ5/
Code of Conduct: http://python.org/psf/codeofconduct/