[Python-Dev] PEP 435 -- Adding an Enum type to the Python standard library (original) (raw)
Steven D'Aprano steve at pearwood.info
Sun Apr 21 03:29:54 CEST 2013
- Previous message: [Python-Dev] PEP 435 -- Adding an Enum type to the Python standard library
- Next message: [Python-Dev] PEP 435 -- Adding an Enum type to the Python standard library
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 21/04/13 05:42, Barry Warsaw wrote:
On Apr 13, 2013, at 12:51 PM, Steven D'Aprano wrote:
I think that's too strong a restriction. I would expect to be able to do this:
class Insect(Enum): wsap = 1 # Oops, needed for backward compatibility, do not remove. wasp = 1 # Preferred. Use this in new code. bee = 2 ant = 3
Or at the very least: class Insect(Enum): wasp = wsap = 1 bee = 2 ant = 3 What's the justification for this restriction? I have looked in the PEP, and didn't see one. If you allowed this, there would be no way to look up an enumeration item by value. This is necessary for e.g. storing the value in a database. If you know that the "insect" column is an INTEGER that represents an enumeration item of Insect, then you can just store the int value in the column. To reconstitute the actual enumeration item when you read the column back from the database, you need to be able to look up the item by value.
I agree that's a good example of a situation where the user might want unique values. But I don't agree that this is the responsibility of the Enum type itself. Enums are a mapping from name to value, just like dicts:
d = {'wasp': 1, 'bee': 2, 'ant': 3}
There are use-cases where we might want dicts to be 1:1 too, but we don't force that restriction on all dicts. Even if I want to reconstruct the key from the value, doesn't mean that everybody who uses dicts must be prohibited from using duplicate values. We don't even offer a guaranteed 1:1 mapping type in the standard library.
Actual real world enums can and do frequently contain duplicate values, I've previously given examples of such. The ability to have two enums with the same value is in my opinion not just a Nice To Have but is a Must Have.
With the ability to have duplicate values, enums are the One Obvious Way to do it. Without it, the decision process becomes more complex: does my application now, or will it ever, need duplicate values? If there's even a tiny chance it might need them in the future, I cannot risk getting stuck with an enum type that prohibits that.
I would argue that it is the responsibility of enums to start with the least restrictions as is reasonable, and leave additional restrictions up to subclasses, rather than the other way around. (I'll just quietly mention the Liskov Substitution Principle here...) If some people need enums to have unique values, then enforcing that should be their responsibility, and not forced on all users whether they need that restriction or not.
If there is enough demand for that, then perhaps the enum module could provide a standard mechanism for enforcing unique values, via a flag, or a subclass, say. I like the idea of a mixin:
class Insect(UniqueValues, Enum): wasp = 1 bee = 2 ant = 3
But it should be off by default.
Currently, you do this:
>>> myinsect = Insect[databasevalue] but if the values are not unique, you have no way to reliably do it. I don't much like APIs which return sequences (either always or "on demand") or rely on definition order or some other arbitrary discrimination because I don't think any of those are practical in the real world.
Neither do I. I would be perfectly happy for enums to raise ValueError in that case, and leave it up to the caller to either prevent duplicate values from occurring, or to deal with the exception in whichever way makes sense for their application.
I also recall that duplication was a specific anti-feature in the previous python-ideas discussion. It was thought that this would allow for typos in the set of enumeration items to creep in.
Typos occur whether enums allow duplicate values or not. How you deal with such typos depends on whether you are forced to keep it forever, or can define a second enum with the same value and deprecate the typo.
-- Steven
- Previous message: [Python-Dev] PEP 435 -- Adding an Enum type to the Python standard library
- Next message: [Python-Dev] PEP 435 -- Adding an Enum type to the Python standard library
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]