Andrew Barnert wrote: > On Oct 20, 2019, at 03:36, Steve Jorgensen ste...@stevej.name 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 -- 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/SPSAC7RF2W5IYZ2F45MIAUHSWJMXGAQ5/ Code of Conduct: http://python.org/psf/codeofconduct/