[Python-Dev] constant/enum type in stdlib

Michael Foord fuzzyman at voidspace.org.uk
Sun Nov 28 18:05:12 CET 2010


On 28/11/2010 16:28, Michael Foord wrote:
> [snip...]
> I don't think there are *many* competing features, in fact as far as 
> feature requests on python-dev go I think this is a relatively 
> straightforward one with a lot of *agreement* on the basic functionality.
>
> We have had various discussions about what the API should look like, 
> or what the implementation should look like, but I don't think there 
> is a lot of disagreement about basic features. There are some 
> 'optional features'. Many of these can be added later without 
> backwards compatibility issues, so those can profitably be omitted 
> from an initial implementation.
>
> Features as I see them:
>
> Named constant
> --------------
>
> * Nice repr
> * Subclass of the type it represents
> * Trivially easy to convert either to a string (name) and the value it 
> represents
> * If an integer type, can be OR'd with other named constants and 
> retains a useful repr
>
Note that having an OR repr is meaningless *unless* the constants are 
intended to be flags, OR'ing should be specified.

     name = NamedValue('name', value, flags=True)

Where flags defaults to False. Typically you will use this through the 
grouping API anyway - where it can either be a keyword argument 
(slightly annoying because the suggestion is to create the named values 
through keyword arguments) or we can have two group-factory functions:

     Group = make_constants('Group', name1=value1, name2=value2)
     Flags = make_flags('Flags', name1=value1, name2=value2)

It is sensible if flag values are only powers of 2; we could enforce 
that or not... (Another one for the optional feature list.)

I forgot auto-enumeration (specifying names only and having values 
autogenerated) from the optional feature set by the way. I think Antoine 
strongly disapproves of this feature because it reminds him of C enums.

Mark Dickinson thinks that the flags feature could be an optional 
feature too. If we have ORing it makes sense to have ANDing, so I guess 
they belong together. I think there is value in it though.

I realise that the optional feature list is now not small, and 
implementing all of it would create the "franken-api" Nick is worried 
about. The minimal feature list is nicely small though and provides 
useful functionality.

All the best,

Michael

>
> Grouped constants
> ----------------
> * Easy to create a group of named constants, accessible as attributes 
> on group object
> * Capability to go from name or value to corresponding constants
>
>
> Optional Features
> ---------------
>
> * Ability to dynamically add new named values to a group. (Suggested 
> by Guido)
> * Ability to test if a name or value is in a group
> * Ability to list all names in a group
> * ANDing as well as ORing
> * Constants are unique
> * OR'ing with an integer will look up the name (or calculate it if the 
> int itself represents flags that have already been OR'd) and return a 
> named value (with useful repr) instead of just an integer
> * Named constants be named values that can wrap *any* type and not 
> just immutable values. (Note that wrapping mutable types makes 
> providing "from_value" functionality harder *unless* we guarantee that 
> named values are unique. If they aren't unique named values for a 
> mutable type can have different values and there is no single 
> definition of what the named value actually is.)
> Requiring that values only have one name - or alternatively that 
> values on a group could have multiple names (obviously incompatible 
> features).
> * Requiring all names in a group to be of the same type
> * Allow names to be set automatically in a namespace, for example in a 
> class namespace or on a module
> * Allow subclassing and adding of new values only present in subclass
>
>
> I'd rather we agree a suitable (minimal) API and feature set and go to 
> implementation from that.
>
> For wrapping mutable types I'm tempted to say YAGNI. For the standard 
> library wrapping integers meets almost all our use-cases except for 
> one float. (At work we have a decimal constant as it happens.) Perhaps 
> we could require immutable types for groups but allow arbitrary values 
> for individual named values?
>
> For the named values api:
>
> name = NamedValue('name', value)
>
> For the grouping (tentatively accepted as reasonable by Antoine):
>
> Group = make_constants('Group', name1=value1, name2=value2)
> name1, name2 = Group.name1, Group.name1
> flag = name1 | name2
>
> value = int(Group.name1)
> name = Group('name1')
> # alternatively: value = Group.from_name('name1')
> name = Group.from_value(value1)
> # Group(value1) could work only if values aren't strings
> # perhaps: name = Group(value=value1)
>
> Group.new_name = value3 # create new value on the group
> names = Group.all_names()
> # further bikeshedding on spelling of all_names required
> # correspondingly 'all_values' I guess, returning the constants 
> themselves
>
> Some of the optional features couldn't later be added without 
> backwards compatibility concerns (I think the type checking features 
> and requiring unique values for example). We should at least consider 
> these if we are to make adding them later difficult. I would be fine 
> with not having these features.
>
> All the best,
>
> Michael
>
>> Cheers,
>> Nick.
>>
>
>


-- 

http://www.voidspace.org.uk/

READ CAREFULLY. By accepting and reading this email you agree,
on behalf of your employer, to release me from all obligations
and waivers arising from any and all NON-NEGOTIATED agreements,
licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap,
confidentiality, non-disclosure, non-compete and acceptable use
policies (”BOGUS AGREEMENTS”) that I have entered into with your
employer, its partners, licensors, agents and assigns, in
perpetuity, without prejudice to my ongoing rights and privileges.
You further represent that you have the authority to release me
from any BOGUS AGREEMENTS on behalf of your employer.



More information about the Python-Dev mailing list