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/

Reply via email to