Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Georg Brandl
Am 04.05.2013 01:22, schrieb Antoine Pitrou:
 On Sat, 04 May 2013 11:15:17 +1200
 Greg Ewing greg.ew...@canterbury.ac.nz wrote:
 Eli Bendersky wrote:
  I'm just curious what it is about enums that sets everyone on a let's 
  make things safer path. Python is about duck typing, it's absolutely 
  unsafe in the static typing sense, in the most fundamental ways 
  imaginable.
 
 This isn't about catching bugs in the program, it's
 about validating user input. That's a common enough
 task that it deserves to have a convenient way to
 do it correctly.
 
 +1. An enum is basically a bidirectional mapping between some raw
 values and some nice instances, so it deserves a well-defined lookup
 operation in each direction.

Agreed.

Georg

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Nick Coghlan
On Sat, May 4, 2013 at 4:10 PM, Georg Brandl g.bra...@gmx.net wrote:
 Am 04.05.2013 01:22, schrieb Antoine Pitrou:
 On Sat, 04 May 2013 11:15:17 +1200
 Greg Ewing greg.ew...@canterbury.ac.nz wrote:
 Eli Bendersky wrote:
  I'm just curious what it is about enums that sets everyone on a let's
  make things safer path. Python is about duck typing, it's absolutely
  unsafe in the static typing sense, in the most fundamental ways
  imaginable.

 This isn't about catching bugs in the program, it's
 about validating user input. That's a common enough
 task that it deserves to have a convenient way to
 do it correctly.

 +1. An enum is basically a bidirectional mapping between some raw
 values and some nice instances, so it deserves a well-defined lookup
 operation in each direction.

As I see it, there are 3 possible ways forward here:

1. The current PEP, offering only getattr(MyEnum, name).

If code needs to ensure non-enum values are detected immediately (such
as during translation of user input entered at a command prompt), then
they can either create a separate mapping using:

lookup = {m.name, m for m in (getattr(MyEnum, name) for name in
dir(MyEnum)) if isinstance(m, MyEnum)}

or else create a lookup function:

def getmember(enum, name):
m = getattr(enum, name, None)
if not isinstance(m, enum):
raise KeyError({!r} is not a member of {!r}.format(name, enum))
return m

2. We restore __getitem__ on EnumMetaclass *solely* for member lookup
by name (the getmember functionality above). This would leave
__call__ used for the reverse lookup (value to member and hence name)
and __getitem__ for the forward lookup (name to member and hence
value) (Note: given Ethan's comments about his current implementation,
I believe this actually fits nicely with the way
EnumMetaclass.__getattr__ is already implemented)

3. We offer my earlier suggestion of an as_dict() method on the
metaclass, which implements the mapping calculation above. As others
pointed out, this has the same name clash problem as offering
additional non-special methods on namedtuple objects.

I'm now -1 on my own as_dict() suggestion, due to the general name
clash problem for arbitrary enums.

Options 1 and 2 both sound reasonable to me, although I have a
preference for 2 due to the ability to produce a more appropriate
error message when the lookup fails.

Cheers,
Nick.

--
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Greg Ewing

Guido van Rossum wrote:

Code that wants to validate a string the user typed as input. Web
forms just don't work that way.


Maybe validation was a misleading term to use. To be
more precise, I'm talking about taking input to the
program (it needn't come directly from a user, it could
be read from a file or database) that is supposed to
be the name of a Color, and turning it into a Color
instance.

For that purpose, it's convenient to have a function
with only two possible outcomes: it either returns a
Color instance, or raises a ValueError.

The point is that you *shouldn't* have to perform a
separate validation step. You should be able to use
EAFP -- go ahead and perform the conversion, but be
prepared to catch a ValueError at some level and
report it to the user.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Greg Ewing

Nick Coghlan wrote:

1. The current PEP, offering only getattr(MyEnum, name).



2. We restore __getitem__ on EnumMetaclass *solely* for member lookup
by name


3. Use keyword arguments to distinguish two different
ways of calling the enum class:

   MyEnum(value = 1) -- lookup by value
   MyEnum(name = foo) -- lookup by name

MyEnum(1) could be made equivalent to MyEnum(value = 1)
if it's thought that lookup by value will be the most
common or natural case.

Pros: Explicit is better than implicit.

Cons: Not so convenient to get a type-conversion function
to pass to other things.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Phil Connell
On 4 May 2013 07:42, Nick Coghlan ncogh...@gmail.com wrote:
 2. We restore __getitem__ on EnumMetaclass *solely* for member lookup
 by name (the getmember functionality above). This would leave
 __call__ used for the reverse lookup (value to member and hence name)
 and __getitem__ for the forward lookup (name to member and hence
 value) (Note: given Ethan's comments about his current implementation,
 I believe this actually fits nicely with the way
 EnumMetaclass.__getattr__ is already implemented)

This has the advantage of leaving one obvious way to do the 'reverse'
lookup (namely __call__), rather than two redundant alternatives.

Cheers,
Phil
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Antoine Pitrou
On Sat, 4 May 2013 16:42:08 +1000
Nick Coghlan ncogh...@gmail.com wrote:
 On Sat, May 4, 2013 at 4:10 PM, Georg Brandl g.bra...@gmx.net wrote:
  Am 04.05.2013 01:22, schrieb Antoine Pitrou:
  On Sat, 04 May 2013 11:15:17 +1200
  Greg Ewing greg.ew...@canterbury.ac.nz wrote:
  Eli Bendersky wrote:
   I'm just curious what it is about enums that sets everyone on a let's
   make things safer path. Python is about duck typing, it's absolutely
   unsafe in the static typing sense, in the most fundamental ways
   imaginable.
 
  This isn't about catching bugs in the program, it's
  about validating user input. That's a common enough
  task that it deserves to have a convenient way to
  do it correctly.
 
  +1. An enum is basically a bidirectional mapping between some raw
  values and some nice instances, so it deserves a well-defined lookup
  operation in each direction.
 
 As I see it, there are 3 possible ways forward here:

4. Offer classmethods named Enum.by_name() and Enum.by_value().
Simple and explicit.

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Ethan Furman

On 05/04/2013 04:33 AM, Antoine Pitrou wrote:

On Sat, 4 May 2013 16:42:08 +1000
Nick Coghlan ncogh...@gmail.com wrote:

On Sat, May 4, 2013 at 4:10 PM, Georg Brandl g.bra...@gmx.net wrote:

Am 04.05.2013 01:22, schrieb Antoine Pitrou:

On Sat, 04 May 2013 11:15:17 +1200
Greg Ewing greg.ew...@canterbury.ac.nz wrote:

Eli Bendersky wrote:

I'm just curious what it is about enums that sets everyone on a let's
make things safer path. Python is about duck typing, it's absolutely
unsafe in the static typing sense, in the most fundamental ways
imaginable.


This isn't about catching bugs in the program, it's
about validating user input. That's a common enough
task that it deserves to have a convenient way to
do it correctly.


+1. An enum is basically a bidirectional mapping between some raw
values and some nice instances, so it deserves a well-defined lookup
operation in each direction.


As I see it, there are 3 possible ways forward here:


4. Offer classmethods named Enum.by_name() and Enum.by_value().
Simple and explicit.


And then you can't have enum items named by_name and by_value.

--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Eric V. Smith
On 5/4/2013 2:42 AM, Nick Coghlan wrote:
 On Sat, May 4, 2013 at 4:10 PM, Georg Brandl g.bra...@gmx.net wrote:
 Am 04.05.2013 01:22, schrieb Antoine Pitrou:
 On Sat, 04 May 2013 11:15:17 +1200
 Greg Ewing greg.ew...@canterbury.ac.nz wrote:
 Eli Bendersky wrote:
 I'm just curious what it is about enums that sets everyone on a let's
 make things safer path. Python is about duck typing, it's absolutely
 unsafe in the static typing sense, in the most fundamental ways
 imaginable.

 This isn't about catching bugs in the program, it's
 about validating user input. That's a common enough
 task that it deserves to have a convenient way to
 do it correctly.

 +1. An enum is basically a bidirectional mapping between some raw
 values and some nice instances, so it deserves a well-defined lookup
 operation in each direction.
 
 As I see it, there are 3 possible ways forward here:
 
 1. The current PEP, offering only getattr(MyEnum, name).
 
 If code needs to ensure non-enum values are detected immediately (such
 as during translation of user input entered at a command prompt), then
 they can either create a separate mapping using:
 
 lookup = {m.name, m for m in (getattr(MyEnum, name) for name in
 dir(MyEnum)) if isinstance(m, MyEnum)}
 
 or else create a lookup function:
 
 def getmember(enum, name):
 m = getattr(enum, name, None)
 if not isinstance(m, enum):
 raise KeyError({!r} is not a member of {!r}.format(name, enum))
 return m
 
 2. We restore __getitem__ on EnumMetaclass *solely* for member lookup
 by name (the getmember functionality above). This would leave
 __call__ used for the reverse lookup (value to member and hence name)
 and __getitem__ for the forward lookup (name to member and hence
 value) (Note: given Ethan's comments about his current implementation,
 I believe this actually fits nicely with the way
 EnumMetaclass.__getattr__ is already implemented)
 
 3. We offer my earlier suggestion of an as_dict() method on the
 metaclass, which implements the mapping calculation above. As others
 pointed out, this has the same name clash problem as offering
 additional non-special methods on namedtuple objects.
 
 I'm now -1 on my own as_dict() suggestion, due to the general name
 clash problem for arbitrary enums.

To avoid the name collision, namedtuple calls this _asdict().

-- 
Eric.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Antoine Pitrou
On Sat, 04 May 2013 06:37:23 -0700
Ethan Furman et...@stoneleaf.us wrote:
 
  +1. An enum is basically a bidirectional mapping between some raw
  values and some nice instances, so it deserves a well-defined lookup
  operation in each direction.
 
  As I see it, there are 3 possible ways forward here:
 
  4. Offer classmethods named Enum.by_name() and Enum.by_value().
  Simple and explicit.
 
 And then you can't have enum items named by_name and by_value.

You can. Normal shadowing rules apply.

By the same token, you can't have enum items named __str__ or __init__.
How is that a problem? Attribute resolution rules imply some
restrictions, which are well-known to all Python programmers.

But, really, you can decide on another name if you like: __byname__ or
_byname, etc. My point is simply that lookup doesn't *have* to invoke
operators, and explicitly named classmethods are less confusing than
repurposed operators.

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Guido van Rossum
Just to stop the bikeshedding, let's do #2. Put back __getitem__
solely for lookup by name. Keep __call__ (really __new__) for lookup
by value or pass-through for members.

--Guido

On Fri, May 3, 2013 at 11:42 PM, Nick Coghlan ncogh...@gmail.com wrote:
 On Sat, May 4, 2013 at 4:10 PM, Georg Brandl g.bra...@gmx.net wrote:
 Am 04.05.2013 01:22, schrieb Antoine Pitrou:
 On Sat, 04 May 2013 11:15:17 +1200
 Greg Ewing greg.ew...@canterbury.ac.nz wrote:
 Eli Bendersky wrote:
  I'm just curious what it is about enums that sets everyone on a let's
  make things safer path. Python is about duck typing, it's absolutely
  unsafe in the static typing sense, in the most fundamental ways
  imaginable.

 This isn't about catching bugs in the program, it's
 about validating user input. That's a common enough
 task that it deserves to have a convenient way to
 do it correctly.

 +1. An enum is basically a bidirectional mapping between some raw
 values and some nice instances, so it deserves a well-defined lookup
 operation in each direction.

 As I see it, there are 3 possible ways forward here:

 1. The current PEP, offering only getattr(MyEnum, name).

 If code needs to ensure non-enum values are detected immediately (such
 as during translation of user input entered at a command prompt), then
 they can either create a separate mapping using:

 lookup = {m.name, m for m in (getattr(MyEnum, name) for name in
 dir(MyEnum)) if isinstance(m, MyEnum)}

 or else create a lookup function:

 def getmember(enum, name):
 m = getattr(enum, name, None)
 if not isinstance(m, enum):
 raise KeyError({!r} is not a member of {!r}.format(name, enum))
 return m

 2. We restore __getitem__ on EnumMetaclass *solely* for member lookup
 by name (the getmember functionality above). This would leave
 __call__ used for the reverse lookup (value to member and hence name)
 and __getitem__ for the forward lookup (name to member and hence
 value) (Note: given Ethan's comments about his current implementation,
 I believe this actually fits nicely with the way
 EnumMetaclass.__getattr__ is already implemented)

 3. We offer my earlier suggestion of an as_dict() method on the
 metaclass, which implements the mapping calculation above. As others
 pointed out, this has the same name clash problem as offering
 additional non-special methods on namedtuple objects.

 I'm now -1 on my own as_dict() suggestion, due to the general name
 clash problem for arbitrary enums.

 Options 1 and 2 both sound reasonable to me, although I have a
 preference for 2 due to the ability to produce a more appropriate
 error message when the lookup fails.

 Cheers,
 Nick.

 --
 Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe: 
 http://mail.python.org/mailman/options/python-dev/guido%40python.org



-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Larry Hastings

On 05/04/2013 07:01 AM, Eric V. Smith wrote:

On 5/4/2013 2:42 AM, Nick Coghlan wrote:

I'm now -1 on my own as_dict() suggestion, due to the general name
clash problem for arbitrary enums.

To avoid the name collision, namedtuple calls this _asdict().


Although I recall Raymond told me he should have called it asdict_(), 
and reserved all identifiers with trailing underscores.



//arry/
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-04 Thread Guido van Rossum
Hm. Trailing underscores look *really* weird to me.

On Sat, May 4, 2013 at 3:41 PM, Larry Hastings la...@hastings.org wrote:
 On 05/04/2013 07:01 AM, Eric V. Smith wrote:

 On 5/4/2013 2:42 AM, Nick Coghlan wrote:

 I'm now -1 on my own as_dict() suggestion, due to the general name
 clash problem for arbitrary enums.

 To avoid the name collision, namedtuple calls this _asdict().


 Although I recall Raymond told me he should have called it asdict_(), and
 reserved all identifiers with trailing underscores.


 /arry

 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe:
 http://mail.python.org/mailman/options/python-dev/guido%40python.org




-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-03 Thread Greg Ewing

Barry Warsaw wrote:

I still don't get it why this is an issue though, or at least why this is
different than any other getattr on any other class,


It's not a problem that getattr() has this behaviour.
What I'm questioning is the idea that getattr() should
be the only provided way of doing a name-enum lookup,
because that will require everyone to do extra checks
to ensure safety.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-03 Thread Eli Bendersky
On Fri, May 3, 2013 at 6:34 AM, Greg Ewing greg.ew...@canterbury.ac.nzwrote:

 Barry Warsaw wrote:

 I still don't get it why this is an issue though, or at least why this is
 different than any other getattr on any other class,


 It's not a problem that getattr() has this behaviour.
 What I'm questioning is the idea that getattr() should
 be the only provided way of doing a name-enum lookup,
 because that will require everyone to do extra checks
 to ensure safety.


I'm just curious what it is about enums that sets everyone on a let's make
things safer path. Python is about duck typing, it's absolutely unsafe
in the static typing sense, in the most fundamental ways imaginable. When
programmatically invoking a method on a class (say some sort of RPC), we
don't check that the class is of the correct type. We invoke a method, and
if it quacks, that's a good enough duck. If it was actually the wrong
class, something will break later. EAFP Is a central Python tenet, whether
we like it or not. If one looks for static guarantees, Python surely
shouldn't be the preferred language, no?

And concretely, how is this case different from any programmatic attribute
access in Python objects? You can pass dunders to getattr() and it probably
wasn't what you meant, but Python does not do this type checking for you.
Why is an Enum different than any other class?

Eli
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-03 Thread Guido van Rossum
On Fri, May 3, 2013 at 7:14 AM, Eli Bendersky eli...@gmail.com wrote:
 I'm just curious what it is about enums that sets everyone on a let's make
 things safer path. Python is about duck typing, it's absolutely unsafe in
 the static typing sense, in the most fundamental ways imaginable. When
 programmatically invoking a method on a class (say some sort of RPC), we
 don't check that the class is of the correct type. We invoke a method, and
 if it quacks, that's a good enough duck. If it was actually the wrong class,
 something will break later. EAFP Is a central Python tenet, whether we like
 it or not. If one looks for static guarantees, Python surely shouldn't be
 the preferred language, no?

 And concretely, how is this case different from any programmatic attribute
 access in Python objects? You can pass dunders to getattr() and it probably
 wasn't what you meant, but Python does not do this type checking for you.
 Why is an Enum different than any other class?

Let's make that a topic for a separate, more philosophical thread, python-ideas.

Back to this particular issue, I haven't seen code in the style that
Greg proposes in decades, and I don't think it is an important enough
use case to support more directly than through getattr() +
isinstance().

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-03 Thread Greg Ewing

Guido van Rossum wrote:

I haven't seen code in the style that
Greg proposes in decades,


What style are you talking about here?

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-03 Thread Greg Ewing

Eli Bendersky wrote:
I'm just curious what it is about enums that sets everyone on a let's 
make things safer path. Python is about duck typing, it's absolutely 
unsafe in the static typing sense, in the most fundamental ways 
imaginable.


This isn't about catching bugs in the program, it's
about validating user input. That's a common enough
task that it deserves to have a convenient way to
do it correctly.

Imagine if int() had the property that, as well as
accepting strings of decimal digits, it also accepted
the string guido and returned his birthday as a
DateTime object. When people complain, they're told
it's okay, you only need to write

   if s != guido:
  x = int(s)
   else:
  raise ValueError

What would you think of that situation?


Why is an Enum different than any other class?


It's not, that's the whole point. IMO it deserves to
have a convenient way of mapping a valid string
representation -- and nothing else -- to a valid value,
just as much as any other type does.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-03 Thread Antoine Pitrou
On Sat, 04 May 2013 11:15:17 +1200
Greg Ewing greg.ew...@canterbury.ac.nz wrote:
 Eli Bendersky wrote:
  I'm just curious what it is about enums that sets everyone on a let's 
  make things safer path. Python is about duck typing, it's absolutely 
  unsafe in the static typing sense, in the most fundamental ways 
  imaginable.
 
 This isn't about catching bugs in the program, it's
 about validating user input. That's a common enough
 task that it deserves to have a convenient way to
 do it correctly.

+1. An enum is basically a bidirectional mapping between some raw
values and some nice instances, so it deserves a well-defined lookup
operation in each direction.

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-03 Thread Guido van Rossum
On Fri, May 3, 2013 at 4:08 PM, Greg Ewing greg.ew...@canterbury.ac.nz wrote:
 Guido van Rossum wrote:

 I haven't seen code in the style that
 Greg proposes in decades,

 What style are you talking about here?

Code that wants to validate a string the user typed as input. Web
forms just don't work that way. (Command-line flags are a special
case, and there are a slew of specialized parsers for that case.)

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-03 Thread Nick Coghlan
On 4 May 2013 00:17, Eli Bendersky eli...@gmail.com wrote:




 On Fri, May 3, 2013 at 6:34 AM, Greg Ewing greg.ew...@canterbury.ac.nz
wrote:

 Barry Warsaw wrote:

 I still don't get it why this is an issue though, or at least why this
is
 different than any other getattr on any other class,


 It's not a problem that getattr() has this behaviour.
 What I'm questioning is the idea that getattr() should
 be the only provided way of doing a name-enum lookup,
 because that will require everyone to do extra checks
 to ensure safety.


 I'm just curious what it is about enums that sets everyone on a let's
make things safer path. Python is about duck typing, it's absolutely
unsafe in the static typing sense, in the most fundamental ways
imaginable. When programmatically invoking a method on a class (say some
sort of RPC), we don't check that the class is of the correct type. We
invoke a method, and if it quacks, that's a good enough duck. If it was
actually the wrong class, something will break later. EAFP Is a central
Python tenet, whether we like it or not. If one looks for static
guarantees, Python surely shouldn't be the preferred language, no?

 And concretely, how is this case different from any programmatic
attribute access in Python objects? You can pass dunders to getattr() and
it probably wasn't what you meant, but Python does not do this type
checking for you. Why is an Enum different than any other class?

The only reason to use enums at all is to improve logging and error
messages. Thus, designing the API and behaviour of an enum type is mostly a
matter of asking What mistakes are developers likely to make? and How
can the enum design help guide them towards a suitable solution?. The
answers are a combination of API design and providing appropriate details
in error messages.

If a developer doesn't care about those two questions then they would just
use the raw underlying values.

Cheers,
Nick.


 Eli




 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe:
http://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-03 Thread Nick Coghlan
On 4 May 2013 09:34, Guido van Rossum gu...@python.org wrote:

 On Fri, May 3, 2013 at 4:08 PM, Greg Ewing greg.ew...@canterbury.ac.nz
wrote:
  Guido van Rossum wrote:
 
  I haven't seen code in the style that
  Greg proposes in decades,

  What style are you talking about here?

 Code that wants to validate a string the user typed as input. Web
 forms just don't work that way. (Command-line flags are a special
 case, and there are a slew of specialized parsers for that case.)

And for code that really needs it, it is straightforward to use dir(MyEnum)
and isinstance(obj, MyEnum) to get an exact mapping of names to values that
also accounts for aliases.

Cheers,
Nick.


 --
 --Guido van Rossum (python.org/~guido)
 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe:
http://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Barry Warsaw
On May 01, 2013, at 11:54 AM, Larry Hastings wrote:

On 04/30/2013 11:29 PM, Ethan Furman wrote:
 On 04/30/2013 11:18 PM, Barry Warsaw wrote:
 On Apr 28, 2013, at 11:50 PM, Ethan Furman wrote:

 But as soon as:

type(Color.red) is Color  # True
type(MoreColor.red) is MoreColor  # True

 then:

 Color.red is MoreColor.red  # must be False, no?


 If that last statement can still be True, I'd love it if someone  
 showed me
 how.

 class Foo:
  a = object()
  b = object()

 class Bar(Foo):
  c = object()

 Foo.a is Bar.a
 True

 Wow.  I think I'm blushing from embarrassment.

 Thank you for answering my question, Barry.

Wait, what?  I don't see how Barry's code answers your question.  In his
example, type(a) == type(b) == type(c) == object.  You were asking how can
Color.red and MoreColor.red be the same object if they are of different
types?

p.s. They can't.

Sure, why not?  In normal Python, Bar inherits a from Foo, it doesn't define
it so it's exactly the same object.  Thus if you access that object through
the superclass, you get the same object as when you access it through the
subclass.

So Foo.a plays the role of Color.red and Bar.a plays the role of
MoreColor.red.  Same object, thus `Foo.a is Bar.a` is equivalent to `Color.red
is MoreColor.red`.

-Barry
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Barry Warsaw
On May 02, 2013, at 11:44 AM, Greg Ewing wrote:

Barry Warsaw wrote:
 Why isn't getattr() for lookup by name
 good enough?

Because it will find things that are not enum items,
e.g. '__str__'.

Why does that matter?

-Barry
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Ethan Furman

On 05/02/2013 07:57 AM, Barry Warsaw wrote:

On May 01, 2013, at 11:54 AM, Larry Hastings wrote:


On 04/30/2013 11:29 PM, Ethan Furman wrote:

On 04/30/2013 11:18 PM, Barry Warsaw wrote:

On Apr 28, 2013, at 11:50 PM, Ethan Furman wrote:


But as soon as:

type(Color.red) is Color  # True
type(MoreColor.red) is MoreColor  # True

then:

 Color.red is MoreColor.red  # must be False, no?


If that last statement can still be True, I'd love it if someone  showed me
how.


class Foo:
  a = object()
  b = object()

class Bar(Foo):
  c = object()


Foo.a is Bar.a

True


Wow.  I think I'm blushing from embarrassment.

Thank you for answering my question, Barry.


Wait, what?  I don't see how Barry's code answers your question.  In his
example, type(a) == type(b) == type(c) == object.  You were asking how can
Color.red and MoreColor.red be the same object if they are of different
types?

p.s. They can't.


Sure, why not?  In normal Python, Bar inherits a from Foo, it doesn't define
it so it's exactly the same object.  Thus if you access that object through
the superclass, you get the same object as when you access it through the
subclass.

So Foo.a plays the role of Color.red and Bar.a plays the role of
MoreColor.red.  Same object, thus `Foo.a is Bar.a` is equivalent to `Color.red
is MoreColor.red`.


Same object, true, but my question was if `type(Bar.a) is Bar`, and in your 
reply `type(Bar.a) is object`.

--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Guido van Rossum
On Thu, May 2, 2013 at 7:58 AM, Barry Warsaw ba...@python.org wrote:
 On May 02, 2013, at 11:44 AM, Greg Ewing wrote:

Barry Warsaw wrote:
 Why isn't getattr() for lookup by name
 good enough?

Because it will find things that are not enum items,
e.g. '__str__'.

 Why does that matter?

I claim it doesn't.

The name lookup is only relevant if you already know that you have a
valid name of an enum in the class, e.g. if you know that a Color name
was written earlier. If you don't, you should do some other check,
e.g. if x in Color:. (Note that from this you cannot derive that
Color[x] should work.)

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Barry Warsaw
On May 02, 2013, at 08:42 AM, Larry Hastings wrote:

So, for the second time: How can Color.red and MoreColor.red be the same
object when they are of different types?

It's a moot point now given Guido's pronouncement.

-Barry
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Eli Bendersky
On Thu, May 2, 2013 at 8:57 AM, Barry Warsaw ba...@python.org wrote:

 On May 02, 2013, at 08:42 AM, Larry Hastings wrote:

 So, for the second time: How can Color.red and MoreColor.red be the same
 object when they are of different types?

 It's a moot point now given Guido's pronouncement.


Correct. There's no Color.red and MoreColor.red. Subclassing is allowed
only of enums that define no members. So this is forbidden:

 class MoreColor(Color):
...   pink = 17
...
TypeError: Cannot subclass enumerations

But this is allowed:

 class Foo(Enum):
...   def some_behavior(self):
... pass
...
 class Bar(Foo):
...   happy = 1
...   sad = 2
...

Eli
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Greg Ewing

Guido van Rossum wrote:

you should do some other check,
e.g. if x in Color:.


So you don't think it's important to have an easy
way to take user input that's supposed to be a
Color name and either return a Color or raise
a ValueError?

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Greg Ewing

Eli Bendersky wrote:


TypeError: Cannot subclass enumerations


This message might be better phrased as cannot extend
enumerations, since we're still allowing subclassing
prior to defining members.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Ethan Furman

On 05/02/2013 04:45 PM, Greg Ewing wrote:

Eli Bendersky wrote:


TypeError: Cannot subclass enumerations


This message might be better phrased as cannot extend
enumerations, since we're still allowing subclassing
prior to defining members.


I like it, thanks!

--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Eli Bendersky
On Thu, May 2, 2013 at 4:50 PM, Ethan Furman et...@stoneleaf.us wrote:

 On 05/02/2013 04:45 PM, Greg Ewing wrote:

 Eli Bendersky wrote:

  TypeError: Cannot subclass enumerations


 This message might be better phrased as cannot extend
 enumerations, since we're still allowing subclassing
 prior to defining members.


 I like it, thanks!


+1
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Ethan Furman

On 05/02/2013 04:43 PM, Greg Ewing wrote:

Guido van Rossum wrote:

you should do some other check,
e.g. if x in Color:.


So you don't think it's important to have an easy
way to take user input that's supposed to be a
Color name and either return a Color or raise
a ValueError?


I don't believe that's what he said:


The name lookup is only relevant if you already know that you have a
valid name of an enum in the class [...]


User input should qualify, and using getattr(EnumClass, user_input) will get you an AttributeError instead of a 
ValueError if user_input is not valid, but surely you don't mind that small difference.  ;)


--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Nick Coghlan
On Fri, May 3, 2013 at 9:57 AM, Ethan Furman et...@stoneleaf.us wrote:
 On 05/02/2013 04:43 PM, Greg Ewing wrote:

 Guido van Rossum wrote:

 you should do some other check,
 e.g. if x in Color:.


 So you don't think it's important to have an easy
 way to take user input that's supposed to be a
 Color name and either return a Color or raise
 a ValueError?


 I don't believe that's what he said:

 The name lookup is only relevant if you already know that you have a
 valid name of an enum in the class [...]


 User input should qualify, and using getattr(EnumClass, user_input) will get
 you an AttributeError instead of a ValueError if user_input is not valid,
 but surely you don't mind that small difference.  ;)

 int(getattr(C(), __str__))
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: int() argument must be a string or a number, not 'method-wrapper'

That's the problem Greg is complaining about: when you use getattr to
do the name-enum member conversion, you have to do your own checking
to exclude method names.

This is part of why I think enums should offer an as_dict() method
that returns an ordered dictionary.

Cheers,
Nick.

--
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-02 Thread Barry Warsaw
On May 03, 2013, at 11:06 AM, Nick Coghlan wrote:

 User input should qualify, and using getattr(EnumClass, user_input) will get
 you an AttributeError instead of a ValueError if user_input is not valid,
 but surely you don't mind that small difference.  ;)

 int(getattr(C(), __str__))
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: int() argument must be a string or a number, not 'method-wrapper'

That's the problem Greg is complaining about: when you use getattr to
do the name-enum member conversion, you have to do your own checking
to exclude method names.

This is part of why I think enums should offer an as_dict() method
that returns an ordered dictionary.

Should this be allowed then?

class Transformations(Enum):
as_int = 1
as_dict = 2
as_tuple = 3

?

I still don't get it why this is an issue though, or at least why this is
different than any other getattr on any other class, or even Enums.  I mean,
you could do a getattr on any other class or instance with any random user
input and there's no guarantee you could pass it straight to int() or any
other conversion type.  So you pretty much have to be prepared to capture
exceptions anyway.

-Barry
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-01 Thread Barry Warsaw
On Apr 29, 2013, at 11:10 AM, Stephen J. Turnbull wrote:

Ethan thinks that Seasons(3) is a typecast, not an access into a
mapping (which would be better expressed by Seasons[3]).  Ie, the
inverse of int(AUTUMN).

This is consistent with the AUTUMN is-a Seasons position that Ethan
and Guido take.  It's inconsistent with the AUTUMN is-a
Seasons_VALUE implementation of Flufl.Enum.

I think this sums it up perfectly.  I get that using class definition syntax
is what sends people down Ethan's path.

-Barry
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-01 Thread Barry Warsaw
On Apr 28, 2013, at 07:46 PM, Ethan Furman wrote:

and similarly, Enum behavior /should be/ (in my opinion ;)

Season.AUTUMN is Season('AUTUMN') is Season(3)

I think you'll have a problem with this.  flufl.enum did this, but it has an
inherent conflict, which is why we removed the getattr-like behavior.

class Things(Enum):
foo = 'bar'
bar = 'foo'

What does Things('foo') return?

Note that it doesn't matter if that's spelled Things['foo'].

Whether it's defined as lookup or instance creation, you should only map
values to items, and not attribute names to items, and definitely not both.
Let getattr() do attribute name lookup just like normal.

-Barry
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-01 Thread Barry Warsaw
On Apr 29, 2013, at 03:36 PM, Steven D'Aprano wrote:

That's not how I understand it. I expected that the correct way to use 
enums is with identity checks:

if arg is Season.SUMMER: 
 handle_summer()

It's certainly the way I've recommended to use them.  I think `is` reads
better in context, and identity checks are usually preferred for singletons,
which enum items are.  You can use equality checks, but think about this:

if thing == None:

vs.

if thing is None:

-Barry
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-01 Thread Barry Warsaw
On Apr 28, 2013, at 11:50 PM, Ethan Furman wrote:

But as soon as:

   type(Color.red) is Color  # True
   type(MoreColor.red) is MoreColor  # True

then:

Color.red is MoreColor.red  # must be False, no?


If that last statement can still be True, I'd love it if someone showed me
how.

class Foo:
a = object()
b = object()

class Bar(Foo):
c = object()

 Foo.a is Bar.a
True

-Barry
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-01 Thread Ethan Furman

On 04/30/2013 11:18 PM, Barry Warsaw wrote:

On Apr 28, 2013, at 11:50 PM, Ethan Furman wrote:


But as soon as:

   type(Color.red) is Color  # True
   type(MoreColor.red) is MoreColor  # True

then:

Color.red is MoreColor.red  # must be False, no?


If that last statement can still be True, I'd love it if someone showed me
how.


class Foo:
 a = object()
 b = object()

class Bar(Foo):
 c = object()


Foo.a is Bar.a

True


Wow.  I think I'm blushing from embarrassment.

Thank you for answering my question, Barry.

--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-01 Thread Glenn Linderman

On 4/30/2013 11:08 PM, Barry Warsaw wrote:

On Apr 28, 2013, at 07:46 PM, Ethan Furman wrote:


and similarly, Enum behavior /should be/ (in my opinion ;)

Season.AUTUMN is Season('AUTUMN') is Season(3)

I think you'll have a problem with this.  flufl.enum did this, but it has an
inherent conflict, which is why we removed the getattr-like behavior.

class Things(Enum):
 foo = 'bar'
 bar = 'foo'

What does Things('foo') return?

Note that it doesn't matter if that's spelled Things['foo'].

Whether it's defined as lookup or instance creation, you should only map
values to items, and not attribute names to items, and definitely not both.
Let getattr() do attribute name lookup just like normal.


I agree that it is confusing to be able to index by either the name of 
the enum or its value, in the same method.  The current implementation 
prefers the names, but will check values if the name is not found, I 
discovered by experimentation, after reading the tests.  But when there 
are conflicts (which would be confusing at best), the inability to look 
up some enumerations by value, because the one with that name is found 
first, would be even more confusing.


Can Things('foo') lookup by name and Things['foo'] lookup by value? Or 
does that confuse things too?
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-01 Thread Barry Warsaw
On May 01, 2013, at 12:19 AM, Glenn Linderman wrote:

Can Things('foo') lookup by name and Things['foo'] lookup by value? Or does
that confuse things too?

I think it confuses things too much.  Why isn't getattr() for lookup by name
good enough?  It is for regular classes.

-Barry
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-01 Thread Larry Hastings

On 04/30/2013 11:29 PM, Ethan Furman wrote:

On 04/30/2013 11:18 PM, Barry Warsaw wrote:

On Apr 28, 2013, at 11:50 PM, Ethan Furman wrote:


But as soon as:

   type(Color.red) is Color  # True
   type(MoreColor.red) is MoreColor  # True

then:

Color.red is MoreColor.red  # must be False, no?


If that last statement can still be True, I'd love it if someone 
showed me

how.


class Foo:
 a = object()
 b = object()

class Bar(Foo):
 c = object()


Foo.a is Bar.a

True


Wow.  I think I'm blushing from embarrassment.

Thank you for answering my question, Barry.


Wait, what?  I don't see how Barry's code answers your question.  In his 
example, type(a) == type(b) == type(c) == object.  You were asking how 
can Color.red and MoreColor.red be the same object if they are of 
different types?


p.s. They can't.


//arry/
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-05-01 Thread Greg Ewing

Barry Warsaw wrote:

Why isn't getattr() for lookup by name
good enough?


Because it will find things that are not enum items,
e.g. '__str__'.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Greg Ewing

Steven D'Aprano wrote:

On 29/04/13 10:29, Ethan Furman wrote:


   - bool(1)# True
   - int('11')  # 11
   - str(var)   # whatever var had in it, now as a str


I think that's a red herring, because you're comparing the use of the 
object constructor with look-up by name.


How does what bool() is doing differ from a lookup?
It's not constructing a new instance. Neither is
int() in the cases where the argument is in the
range of values that it caches.

More generally, the built-in types can be thought
of as coercion functions -- they take an argument
and return some related value from the type's
repertoire. Whether they do that by constructing
a new object or not is an implementation detail.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Cameron Simpson
On 28Apr2013 19:46, Ethan Furman et...@stoneleaf.us wrote:
| int, float, and bool all have object constructors that take the
| given string and return a matching instance; int /may/ return a
| pre-existing instance, bool /will/ return a pre-existing instance.

I think Guido's already pointed out this:

   bool('False')
  True

| As I've stated before, 'bool's are the closest existing data type to
| enums, in that bools use the object constructor to convert the
| incoming parameter to an existing bool instance, of which there will
| only ever be two.
| 
| bool(9) is bool('maybe') is bool(True) is True
| 
| and similarly, Enum behavior /should be/ (in my opinion ;)
| 
| Season.AUTUMN is Season('AUTUMN') is Season(3)

I think that would be _efficient_, but as an outside user I wouldn't
necessarily expect it unless I'd ready the spec very closely and
the spec was explicit about it.

Coming from (in the fairly distant past) a C background, I naively
think of enums as nicely named ordinals of some kind and expect to
compare them with ==, not is.

If you want to guarantee is, be my guest though.
I don't know how that might make things go with some hypothetical subclass
with many many and extensible enum values.

| Like it or not, when you write `class Season(Enum)` a new *type* is
| created called Season, and Season(x) should either return a Season
| instance that matches x or raise.  Having a match and raising anyway
| just doesn't seem to me to be the Python Way.

I'm +1 on all of this.

[...]
| I'm not sure whether flufl.enums support creating additional instances after 
the event, but if it did, I would expect
| that I could say Season('WET') to get a new instance. I am indifferent to 
whether or not Season('AUTUMN') should return
| the existing AUTUMN enum value.
| 
| Adding more enumerators after the fact should not be supported;
| there is subclassing for that. Not worth actively preventing, but
| not encouraged.

I'd go a bit further here: I'd take this final sentence as being
-0 on preventing adding more enumerals(?), whereas I'm a solid -1
on preventing it. By all means not actively support it, but very
against doing things that make it hard for a subclass to support
it.

Just 2c,
-- 

Would you remember a one-line .sig? - Paul Thompson, thomp...@apple.com
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Antoine Pitrou
On Sun, 28 Apr 2013 17:29:35 -0700
Ethan Furman et...@stoneleaf.us wrote:
 
 Not only is this inconsistent with the rest of Python*, but it's going to be 
 a PITA for data storage/retrieval:
 
  datastore = dbf.Table('storage.dbf', 'event_name C(50); date D; season 
 SEASON')
 
  def retrieve_record(...):
  result = []
  for field_type, field_data in record:
  result.append(field_type(field_data))

I've never seen any kind of data retrieval which works like that.
Would you care to explain us the context?

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Ethan Furman

On 04/28/2013 09:54 PM, Guido van Rossum wrote:

On Sunday, April 28, 2013, Ethan Furman wrote:


Enums are the same: they could return brand new instances every time, and 
programs using `==` to compare will keep
on working.  That they don't is an implementation detail.


Whoa. In this case the identity property is not just an implementation issue, 
it is part of the spec. Same for bool.
(But == works too.)


I realize that, and I have no problems with the singleton (multiton?) approach; however, part of the spec is that a 
subclass shares the enum items, and if the enum items are actual instances of the type that will no longer be correct.


In other words, currently:

  class Color(Enum):
  red = 1
  green = 2
  blue = 3

  class MoreColor(Color):
  cyan = 4
  magenta = 5
  yellow = 6
  black = 7

  MoreColor.red is Color.red  # True

But as soon as:

  type(Color.red) is Color  # True
  type(MoreColor.red) is MoreColor  # True

then:

   Color.red is MoreColor.red  # must be False, no?


If that last statement can still be True, I'd love it if someone showed me how.

--
~Ethan~

P.S.  Apologies for the additional post.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Greg Ewing

Cameron Simpson wrote:

I'd go a bit further here: I'd take this final sentence as being
-0 on preventing adding more enumerals(?), whereas I'm a solid -1
on preventing it. By all means not actively support it, but very
against doing things that make it hard for a subclass to support
it.


I had another thought about subclassing. I don't think it
would be a good idea to totally forbid subclassing classes
derived from Enum, because you may want to define an Enum
subclass for the purpose of creating a new *kind* of enum.

For example,

   class FancyEnum(Enum):

  def fancy_str(self):
 return str(self) +  with bells on

If subclassing a subclass of Enum were prevented somehow,
you would't be able to create any actual enums based on
FancyEnum.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Greg Ewing

Guido van Rossum wrote:

(2a. We could also allow Color('red') is Color.red, but that could be
confusing, and we can already do that with getattr(Color, 'red'),


That doesn't quite give you the same thing. Presumably
Color('__str__') would be expected to raise a ValueError,
for example.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Steven D'Aprano
On Sun, Apr 28, 2013 at 11:50:16PM -0700, Ethan Furman wrote:

 In other words, currently:
 
   class Color(Enum):
   red = 1
   green = 2
   blue = 3
 
   class MoreColor(Color):
   cyan = 4
   magenta = 5
   yellow = 6
   black = 7
 
   MoreColor.red is Color.red  # True

Correct.


 But as soon as:
 
   type(Color.red) is Color  # True
   type(MoreColor.red) is MoreColor  # True

I don't believe this is correct. As I understand it, the proposal is the 
weaker guarantee:

  isinstance(Color.red, Color) # True, possibly using __instancecheck__


Since red is not defined by MoreColor, there's no reason to expect that 
it will be a MoreColor instance. As far as I understand it, there is no 
guarantee that

  isinstance(MoreColor.red, MoreColor)

will be true, even if that is possible using __instancecheck__.



-- 
Steven
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Eli Bendersky
On Sun, Apr 28, 2013 at 12:32 PM, Ethan Furman et...@stoneleaf.us wrote:

 Example enumeration:

 class Seasons(Enum):
 SPRING = 1
 SUMMER = 2
 AUTUMN = 3
 WINTER = 4

 days_in_year = 365

 @property
 def avg_temp(self):
 return (75, 92, 66, 33)[int(self)+1] # enums are 1-based


 Definite Issues:

   - should enum items be of the type of the Enum class? (i.e. type(SPRING)
 is Seasons)

   - should an enum item be selectable via __call__ instead of __getitem__
 (i.e. Seasons(3) is AUTUMN)

   - should days_in_year be enumerated?

   - should avg_temp be enumerated?

   - for the above two, how should they be included/excluded?


Thanks for the summary. One issue I don't see addressed here is
int-compatibility. Am I correct to assume that nothing changes w.r.t. that,
and that an IntEnum subclass of Enum will be provided which is
isinstance(integer)? Does that become straightforward by nature of enum
values being the type of their enumerations?

Eli
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Eli Bendersky
On Sun, Apr 28, 2013 at 9:09 PM, Guido van Rossum gu...@python.org wrote:

 On Sun, Apr 28, 2013 at 3:28 PM, Nick Coghlan ncogh...@gmail.com wrote:
  Functions are descriptors, so this rule already covers ordinary methods.
 The
  slight concern I have with making the duck typed exclusion only
 descriptors
  (rather than descriptors and callables) is that it means things like
  functools.partial objects will be treated as enum values rather than as
  static methods. OTOH, explicitly wrapping such callables in staticmethod
  should still work, so the simpler rule is probably better.

 I think the practice of using callables (other than possibly decorated
 functions) as global variables is confusing at best, even in a
 non-enum class, since few people will be able to predict whether they
 will get the instance passed or not. So I think the rule looking only
 for descriptors is superior.

 There has been a whole lot more discussion in this thread. I am now
 asking everyone to stop bikeshedding, even if you think *your* point
 isn't bikeshedding -- the cacophony makes it impossible to hear
 anyone.

 There are a few more issues on which I'd like to pronounce.

 1. The order in which iter(Color) should produce the items. The
 argument has been made that definition order is the only order that is
 not easily reconstructed, and I agree. So let's use definition order,
 even if that means it can't be implemented in Python 2.

 2. Whether Color(x) should be allowed, and what it should mean. Taking
 the example of bool, it should return an existing enum if the argument
 is either a Color or one of the values used for Color items (choosing
 one somehow if there are multiple with the same value -- it doesn't
 matter which one), and raise an exception if the argument is neither.
 E.g.:

   class Color(Enum):
  red = 1
  white = 2
  blue = 3

 x = Color.red
 assert Color(x) is Color.red
 assert Color(1) is Color.red
 Color(42)  # raises

 (2a. We could also allow Color('red') is Color.red, but that could be
 confusing, and we can already do that with getattr(Color, 'red'), and
 bool('False') doesn't return False anyway, so let's not do that.)

 (2b. Let's not hypergeneralize and try to make bool and enums
 completely alike. I see no advantage to adding bool.True and
 bool.False, nor in making enums final classes, or giving a meaning
 to iter(bool). Type bool is its own thing, but that doesn't mean enums
 can't emulate aspects of it.)

 Together with my pronouncements earlier in this thread I am hoping
 that Eli and Barry will update the PEP and implementation (let's give
 them a week) and everyone else will quiet down. I realize we're
 deviating further from flufl.enum than our initial hope, but I think
 the outcome is better.


Sounds like a plan. Thanks for trying to converge things, Guido. Personally
I don't have strong opinions about the changes inflicted by recent threads,
but I may stumble into something as I dive deeper. I was away for a couple
of days and a lot has changed - I'll need some time to catch up, but
updating the PEP by the end of the week seems reasonable.

Eli
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Eli Bendersky
On Sun, Apr 28, 2013 at 9:09 PM, Guido van Rossum gu...@python.org wrote:

 On Sun, Apr 28, 2013 at 3:28 PM, Nick Coghlan ncogh...@gmail.com wrote:
  Functions are descriptors, so this rule already covers ordinary methods.
 The
  slight concern I have with making the duck typed exclusion only
 descriptors
  (rather than descriptors and callables) is that it means things like
  functools.partial objects will be treated as enum values rather than as
  static methods. OTOH, explicitly wrapping such callables in staticmethod
  should still work, so the simpler rule is probably better.

 I think the practice of using callables (other than possibly decorated
 functions) as global variables is confusing at best, even in a
 non-enum class, since few people will be able to predict whether they
 will get the instance passed or not. So I think the rule looking only
 for descriptors is superior.

 There has been a whole lot more discussion in this thread. I am now
 asking everyone to stop bikeshedding, even if you think *your* point
 isn't bikeshedding -- the cacophony makes it impossible to hear
 anyone.

 There are a few more issues on which I'd like to pronounce.

 1. The order in which iter(Color) should produce the items. The
 argument has been made that definition order is the only order that is
 not easily reconstructed, and I agree. So let's use definition order,
 even if that means it can't be implemented in Python 2.

 2. Whether Color(x) should be allowed, and what it should mean. Taking
 the example of bool, it should return an existing enum if the argument
 is either a Color or one of the values used for Color items (choosing
 one somehow if there are multiple with the same value -- it doesn't
 matter which one), and raise an exception if the argument is neither.


I don't feel strongly about allowing ()-lookup in addition to []-lookup,
but in this paragraph the issue of multiple definitions has sneaked in :-)
flufl.enum disallows this:

class Color(Enum):
  red = 1
  blue = 2
  green = 1 # oops!

Has it been decided that this is now allowed? If this is indeed the case,
then Color(1) is a problem. The options are:

A. Return either Color.red or Color.green
B. Throwing an error

Do we have a decision on this? Personally I think the latter is better; the
former is error prone and doesn't seem to be useful too often.

Eli [trying to tie loose ends for updating the PEP].
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Larry Hastings


On 04/29/2013 06:51 AM, Eli Bendersky wrote:

flufl.enum disallows this:

class Color(Enum):
  red = 1
  blue = 2
  green = 1 # oops!

Has it been decided that this is now allowed? If this is indeed the 
case, then Color(1) is a problem. The options are:


A. Return either Color.red or Color.green
B. Throwing an error

Do we have a decision on this? Personally I think the latter is 
better; the former is error prone and doesn't seem to be useful too often.


Eli [trying to tie loose ends for updating the PEP].


Would you disallow this too?

   class Color(Enum):
  red = 1
  blue = 2
   Color.green = Color.red


IMO the more Pythonic behavior would be to allow multiple names for the 
same value, and your example should produce the same result as my 
example.  I'm not convinced enums are special enough to break the rules.


See also consenting adults,


//arry/
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Guido van Rossum
On Mon, Apr 29, 2013 at 5:24 AM, Eli Bendersky eli...@gmail.com wrote:
 Thanks for the summary. One issue I don't see addressed here is
 int-compatibility. Am I correct to assume that nothing changes w.r.t. that,
 and that an IntEnum subclass of Enum will be provided which is
 isinstance(integer)? Does that become straightforward by nature of enum
 values being the type of their enumerations?

Correct, we'll still need an IntEnum subclass of Enum. I have no idea
how this works out in the implementation, sorry.

--
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Guido van Rossum
On Mon, Apr 29, 2013 at 6:51 AM, Eli Bendersky eli...@gmail.com wrote:
 I don't feel strongly about allowing ()-lookup in addition to []-lookup, but
 in this paragraph the issue of multiple definitions has sneaked in :-)
 flufl.enum disallows this:

 class Color(Enum):
   red = 1
   blue = 2
   green = 1 # oops!

 Has it been decided that this is now allowed?

I don't recall if it was decided. I think it should be possible to
create aliases like this. The main thing I care about is that
Color.green == Color.red. I wouldn't mind if Color.green ends up as
just a different name for the Color.red object. The most common use
case is probably providing backwards compatibility with an old version
of the enum when renaming something -- e.g. one could write

class Color(Enum):
  ...
  turquoise = 42
  aqua = turquoise  # I can't tell them apart

Here the metaclass would see two different names with the same value (42).

 If this is indeed the case, then Color(1) is a problem. The options are:

 A. Return either Color.red or Color.green
 B. Throwing an error

 Do we have a decision on this? Personally I think the latter is better; the
 former is error prone and doesn't seem to be useful too often.

I think it should be A, and the choice should be the first one in
definition order.

--
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Ethan Furman

On 04/29/2013 09:30 AM, Larry Hastings wrote:


On 04/29/2013 06:51 AM, Eli Bendersky wrote:

flufl.enum disallows this:

class Color(Enum):
  red = 1
  blue = 2
  green = 1 # oops!

Has it been decided that this is now allowed? If this is indeed the case, then 
Color(1) is a problem. The options are:


At this point I think the best course is to not allow duplicates directly in the enum definition, but allow them after 
the fact:


-- class Color(Enum):
... red = 1
... green = 2
... blue = 3

-- Color.grene = Color.green  # stupid legacy typo

This gives us both some protection against accidental duplicates, while still allowing them when necessary; also, no 
confusion about which is the canonical name.


Guido?

--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Steven D'Aprano

On 30/04/13 02:42, Guido van Rossum wrote:

On Mon, Apr 29, 2013 at 6:51 AM, Eli Bendersky eli...@gmail.com wrote:

I don't feel strongly about allowing ()-lookup in addition to []-lookup, but
in this paragraph the issue of multiple definitions has sneaked in :-)
flufl.enum disallows this:

class Color(Enum):
   red = 1
   blue = 2
   green = 1 # oops!

Has it been decided that this is now allowed?


I don't recall if it was decided. I think it should be possible to
create aliases like this. The main thing I care about is that
Color.green == Color.red.


I believe that Barry had decided that it should be prohibited. I objected, and 
Nick pointed out that although declaring two enums with the same value inside 
the class is prohibited, aliases are supported by adding them from the outside:

class Color(Enum):
red = 1
blue = 2

Color.green = Color.red


which satisfies me.





--
Steven
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Guido van Rossum
On Mon, Apr 29, 2013 at 9:47 AM, Ethan Furman et...@stoneleaf.us wrote:

 At this point I think the best course is to not allow duplicates directly in
 the enum definition, but allow them after the fact:

 -- class Color(Enum):
 ... red = 1
 ... green = 2
 ... blue = 3

 -- Color.grene = Color.green  # stupid legacy typo

 This gives us both some protection against accidental duplicates, while
 still allowing them when necessary; also, no confusion about which is the
 canonical name.

No. Poking a class has a code smell. It should be possible to define
the aliases inside the enum class definition. The canonical one is the
first one in definition order.

--
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Larry Hastings


On 04/29/2013 10:35 AM, Steven D'Aprano wrote:

On 30/04/13 02:42, Guido van Rossum wrote:

On Mon, Apr 29, 2013 at 6:51 AM, Eli Bendersky eli...@gmail.com wrote:
I don't feel strongly about allowing ()-lookup in addition to 
[]-lookup, but

in this paragraph the issue of multiple definitions has sneaked in :-)
flufl.enum disallows this:

class Color(Enum):
   red = 1
   blue = 2
   green = 1 # oops!

Has it been decided that this is now allowed?


I don't recall if it was decided. I think it should be possible to
create aliases like this. The main thing I care about is that
Color.green == Color.red.


I believe that Barry had decided that it should be prohibited. I 
objected, and Nick pointed out that although declaring two enums with 
the same value inside the class is prohibited, aliases are supported 
by adding them from the outside:


class Color(Enum):
red = 1
blue = 2

Color.green = Color.red

which satisfies me.


Assuming that Color(1) always returns the same object, then we could 
also write this:


   class Color(Enum):
red = 1
blue = 2
   Color.green = Color(1)


Which should be identical to

   class Color(Enum):
red = 1
blue = 2
green = 1

To declare that my first example is okay but the second is not strikes 
me as awfully special.  And I do mean awful.



//arry/
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Terry Jan Reedy

On 4/29/2013 8:24 AM, Eli Bendersky wrote:


Thanks for the summary. One issue I don't see addressed here is
int-compatibility. Am I correct to assume that nothing changes w.r.t.
that, and that an IntEnum subclass of Enum will be provided which is
isinstance(integer)? Does that become straightforward by nature of enum
values being the type of their enumerations?


My only concern is that whatever you do does not break transitivity of 
==. Aside from that, I will be happy with whatever you end up with and 
use it as appropriate.






___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Ethan Furman

On 04/29/2013 02:45 PM, Terry Jan Reedy wrote:

On 4/29/2013 8:24 AM, Eli Bendersky wrote:


Thanks for the summary. One issue I don't see addressed here is
int-compatibility. Am I correct to assume that nothing changes w.r.t.
that, and that an IntEnum subclass of Enum will be provided which is
isinstance(integer)? Does that become straightforward by nature of enum
values being the type of their enumerations?


My only concern is that whatever you do does not break transitivity of ==. 
Aside from that, I will be happy with
whatever you end up with and use it as appropriate.


It will not be broken.

--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Guido van Rossum
On Mon, Apr 29, 2013 at 2:45 PM, Terry Jan Reedy tjre...@udel.edu wrote:
 On 4/29/2013 8:24 AM, Eli Bendersky wrote:

 Thanks for the summary. One issue I don't see addressed here is
 int-compatibility. Am I correct to assume that nothing changes w.r.t.
 that, and that an IntEnum subclass of Enum will be provided which is
 isinstance(integer)? Does that become straightforward by nature of enum
 values being the type of their enumerations?


 My only concern is that whatever you do does not break transitivity of ==.
 Aside from that, I will be happy with whatever you end up with and use it as
 appropriate.

This is a trick question though, isn't it? Example:

class Color(Enum):
  red = 1
  white = 2
  blue = 3

class State(Enum):
  idle = 0
  busy = 1

We would have State.busy == 1 and Color.red == 1, so now State.busy ==
Color.red.

--
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-29 Thread Eli Bendersky
On Mon, Apr 29, 2013 at 2:45 PM, Terry Jan Reedy tjre...@udel.edu wrote:

 On 4/29/2013 8:24 AM, Eli Bendersky wrote:

  Thanks for the summary. One issue I don't see addressed here is
 int-compatibility. Am I correct to assume that nothing changes w.r.t.
 that, and that an IntEnum subclass of Enum will be provided which is
 isinstance(integer)? Does that become straightforward by nature of enum
 values being the type of their enumerations?


 My only concern is that whatever you do does not break transitivity of ==.
 Aside from that, I will be happy with whatever you end up with and use it
 as appropriate.


The transitivity of == is not broken by either proposal. In PEP 435, the
split to Enum and IntEnum is made in part for this reason. Enum values
don't compare equal even if they have the same underlying values. IntEnum
values do compare equal to ints, and hence to each other. So:

class Color(Enum):
  red = 1
  blue = 2

class Animal(Enum):
  dog = 2
  sheep = 7

Color.blue != Animal.dog, and neither compares to 2, of course.
However, had both enums been IntEnum, we'd have:

Color.blue == Animal.dog == 2

This is a werdness users of IntEnum have to live with, and that's why it's
explicitly discouraged for 99% of the use-cases.

Eli
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Georg Brandl
Hi all,

I've just read a few dozen enum-related emails, and there are so many more.
I would like to form an opinion about the proposal(s), but I feel I don't
know what the actual issues are anymore.

In the past, somebody usually presented a summary of the issues so far,
and that was a good point for late comers to get up to speed and weigh in.
(It can be here or in the PEP.)  It is also a good point to focus the
discussion (which seems to have wandered quite far from sensible Pythonic
design in places).

Thanks in advance,
Georg

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Ethan Furman

Example enumeration:

class Seasons(Enum):
SPRING = 1
SUMMER = 2
AUTUMN = 3
WINTER = 4

days_in_year = 365

@property
def avg_temp(self):
return (75, 92, 66, 33)[int(self)+1] # enums are 1-based


Definite Issues:

  - should enum items be of the type of the Enum class? (i.e. type(SPRING) is 
Seasons)

  - should an enum item be selectable via __call__ instead of __getitem__ (i.e. 
Seasons(3) is AUTUMN)

  - should days_in_year be enumerated?

  - should avg_temp be enumerated?

  - for the above two, how should they be included/excluded?
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Guido van Rossum
My opinions added

On Sun, Apr 28, 2013 at 12:32 PM, Ethan Furman et...@stoneleaf.us wrote:
 Example enumeration:

 class Seasons(Enum):
 SPRING = 1
 SUMMER = 2
 AUTUMN = 3
 WINTER = 4

 days_in_year = 365

 @property
 def avg_temp(self):
 return (75, 92, 66, 33)[int(self)+1] # enums are 1-based


 Definite Issues:

   - should enum items be of the type of the Enum class? (i.e. type(SPRING)
 is Seasons)

IMO Yes.

   - should an enum item be selectable via __call__ instead of __getitem__
 (i.e. Seasons(3) is AUTUMN)

No opinion.

   - should days_in_year be enumerated?

Yes. (If you don't want it to be, and it's not a method/descriptor,
move it out of the class.)

   - should avg_temp be enumerated?

IMO No.

   - for the above two, how should they be included/excluded?

IMO Everything should be enumerated except
(a) things with a __get__() method (i.e. descriptors)
(b) __dunder__ names

Also, I believe there's still an issue on the order in which items are
returned by iter(Seasons), but I don't know which way this is heading.

--
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Ethan Furman

On 04/28/2013 01:02 PM, Guido van Rossum wrote:


My opinions added


Mine also now added.



Example enumeration:

class Seasons(Enum):
 SPRING = 1
 SUMMER = 2
 AUTUMN = 3
 WINTER = 4

 days_in_year = 365

 @property
 def avg_temp(self):
 return (75, 92, 66, 33)[int(self)+1] # enums are 1-based


Definite Issues:

   - should enum items be of the type of the Enum class? (i.e. type(SPRING)
is Seasons)


IMO Yes.


I agree.


   - should an enum item be selectable via __call__ instead of __getitem__
(i.e. Seasons(3) is AUTUMN)


No opinion.


I think the callable syntax should be supported for database integration and consistency with every (?) other type in 
Python.  No opinion about the __getitem__ portion.




   - should days_in_year be enumerated?


Yes. (If you don't want it to be, and it's not a method/descriptor,
move it out of the class.)


Making it a property to have it in the class certainly works for me.



   - should avg_temp be enumerated?


IMO No.


I agree.



   - for the above two, how should they be included/excluded?


IMO Everything should be enumerated except
(a) things with a __get__() method (i.e. descriptors)
(b) __dunder__ names


This also works for me.



Also, I believe there's still an issue on the order in which items are
returned by iter(Seasons), but I don't know which way this is heading.


As somebody pointed out earlier, the only order which cannot be reconstructed after the fact is definition order (value 
order can be, lexical order can be, etc.).  So my vote is to have the default iteration order be the original definition 
order, as any other desired order can be added to the class.


--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Antoine Pitrou
On Sun, 28 Apr 2013 13:02:11 -0700
Guido van Rossum gu...@python.org wrote:
 
- for the above two, how should they be included/excluded?
 
 IMO Everything should be enumerated except
 (a) things with a __get__() method (i.e. descriptors)
 (b) __dunder__ names

I think it would be nice to define regular methods on enums.

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Nick Coghlan
On 29 Apr 2013 07:32, Antoine Pitrou solip...@pitrou.net wrote:

 On Sun, 28 Apr 2013 13:02:11 -0700
 Guido van Rossum gu...@python.org wrote:
 
 - for the above two, how should they be included/excluded?
 
  IMO Everything should be enumerated except
  (a) things with a __get__() method (i.e. descriptors)
  (b) __dunder__ names

 I think it would be nice to define regular methods on enums.

Functions are descriptors, so this rule already covers ordinary methods.
The slight concern I have with making the duck typed exclusion only
descriptors (rather than descriptors and callables) is that it means things
like functools.partial objects will be treated as enum values rather than
as static methods. OTOH, explicitly wrapping such callables in staticmethod
should still work, so the simpler rule is probably better.

Cheers,
Nick.


 Regards

 Antoine.


 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe:
http://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Antoine Pitrou
On Mon, 29 Apr 2013 08:28:34 +1000
Nick Coghlan ncogh...@gmail.com wrote:
 On 29 Apr 2013 07:32, Antoine Pitrou solip...@pitrou.net wrote:
 
  On Sun, 28 Apr 2013 13:02:11 -0700
  Guido van Rossum gu...@python.org wrote:
  
  - for the above two, how should they be included/excluded?
  
   IMO Everything should be enumerated except
   (a) things with a __get__() method (i.e. descriptors)
   (b) __dunder__ names
 
  I think it would be nice to define regular methods on enums.
 
 Functions are descriptors, so this rule already covers ordinary methods.

Oh, I had missed that.

Regards

Antoine.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Ethan Furman

On 04/28/2013 02:29 PM, Antoine Pitrou wrote:

On Sun, 28 Apr 2013 13:02:11 -0700
Guido van Rossum gu...@python.org wrote:



   - for the above two, how should they be included/excluded?


IMO Everything should be enumerated except
(a) things with a __get__() method (i.e. descriptors)
(b) __dunder__ names


I think it would be nice to define regular methods on enums.


No worries -- regular methods have a __get__.

--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Steven D'Aprano

On 29/04/13 06:02, Guido van Rossum wrote:

My opinions added

On Sun, Apr 28, 2013 at 12:32 PM, Ethan Furman et...@stoneleaf.us wrote:




Definite Issues:

   - should enum items be of the type of the Enum class? (i.e. type(SPRING)
is Seasons)


IMO Yes.


+1



   - should an enum item be selectable via __call__ instead of __getitem__
(i.e. Seasons(3) is AUTUMN)


No opinion.


Does anyone know why this is even an issue? Is this pure bike-shedding over the 
API, or are there
technical reasons for choosing one over the other?



   - should days_in_year be enumerated?


Yes. (If you don't want it to be, and it's not a method/descriptor,
move it out of the class.)


+1, but see below.



   - should avg_temp be enumerated?


IMO No.


   - for the above two, how should they be included/excluded?


IMO Everything should be enumerated except
(a) things with a __get__() method (i.e. descriptors)
(b) __dunder__ names


+1 on excluding dunder names. +0 on excluding things with __get__.

I have also suggested that that the enum package provide a decorator
which can be used to explicitly flag values to *not* be turned into
enum values. See here:

http://mail.python.org/pipermail/python-dev/2013-April/125641.html

Even if the Enum class doesn't support this feature, I ask that it be
written in such a way that a subclass could add it (i.e. please expose
a public method for deciding what to exclude).




--
Steven
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread PJ Eby
On Sun, Apr 28, 2013 at 7:37 PM, Steven D'Aprano st...@pearwood.info wrote:
 I have also suggested that that the enum package provide a decorator
 which can be used to explicitly flag values to *not* be turned into
 enum values. See here:

 http://mail.python.org/pipermail/python-dev/2013-April/125641.html

In that example, 'food = property(lambda:skip)' would work in a
pinch. (Granted, it wouldn't be a *class* attribute, but you can make
a class attribute by assiging it after class creation is completed.)

And if you want to make your enum instances callable, ISTM the right
(or at least the One Obvious) way to do it is to add a __call__ method
to the class.


 Even if the Enum class doesn't support this feature, I ask that it be
 written in such a way that a subclass could add it (i.e. please expose
 a public method for deciding what to exclude).

Since you can exclude anything by it having a __get__ method, or
include it by making it *not* have a __get__ method, I'm not sure what
use case you're actually looking for.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Glenn Linderman

On 4/28/2013 4:37 PM, Steven D'Aprano wrote:

I have also suggested that that the enum package provide a decorator
which can be used to explicitly flag values to *not* be turned into
enum values. See here:

http://mail.python.org/pipermail/python-dev/2013-April/125641.html

Even if the Enum class doesn't support this feature, I ask that it be
written in such a way that a subclass could add it (i.e. please expose
a public method for deciding what to exclude). 


That last comment is very interesting to me... I think it would be good 
if the enum implementation doesn't prevent the creation of a subclass of 
integer enumerations which can be extended so that when arithmetic is 
done on them, that new enumeration values and names can be added to the 
collection (think flag fields). The add ones might have names that do 
not follow the rules for identifiers.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Ethan Furman

On 04/28/2013 04:37 PM, Steven D'Aprano wrote:

On Sun, Apr 28, 2013 at 12:32 PM, Ethan Furman et...@stoneleaf.us wrote:


   - should an enum item be selectable via __call__ instead of __getitem__
(i.e. Seasons(3) is AUTUMN)


Does anyone know why this is even an issue? Is this pure bike-shedding over the 
API, or are there
technical reasons for choosing one over the other?


This is an issue because currently every other type* in Python creates (or 
selects ;) its instances via the call syntax:

  - bool(1)# True
  - int('11')  # 11
  - str(var)   # whatever var had in it, now as a str

But one of the latest changes to flufl.enum was to take out the call syntax, 
and have only getitem syntax

  - Season('AUTUMN')  # raises an exception
  - Season['AUTUMN']  # Season.AUTUMN

Not only is this inconsistent with the rest of Python*, but it's going to be a 
PITA for data storage/retrieval:

datastore = dbf.Table('storage.dbf', 'event_name C(50); date D; season 
SEASON')

def retrieve_record(...):
result = []
for field_type, field_data in record:
result.append(field_type(field_data))

vs.

def retrieve_record(...):
result = []
for field_type, field_data in record:
if isinstance(field_type, Enum):
result.append(field_type[field_data])
else:
result.append(field_type(field_data))

Not being able to use call syntax on the Enum class unnecessarily complicates 
other code.

--
~Ethan~

* Please correct me if I'm wrong.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Steven D'Aprano

On 29/04/13 10:29, Ethan Furman wrote:

On 04/28/2013 04:37 PM, Steven D'Aprano wrote:

On Sun, Apr 28, 2013 at 12:32 PM, Ethan Furman et...@stoneleaf.us wrote:


   - should an enum item be selectable via __call__ instead of __getitem__
(i.e. Seasons(3) is AUTUMN)


Does anyone know why this is even an issue? Is this pure bike-shedding over the 
API, or are there
technical reasons for choosing one over the other?


This is an issue because currently every other type* in Python creates (or 
selects ;) its instances via the call syntax:

   - bool(1)# True
   - int('11')  # 11
   - str(var)   # whatever var had in it, now as a str



I think that's a red herring, because you're comparing the use of the object 
constructor with look-up by name.

Seasons[3] should not be considered as constructing an instance from argument 
3, but a reverse lookup from raw value to enum value. Hence the use of 
__getitem__ rather than __call__.



But one of the latest changes to flufl.enum was to take out the call syntax, 
and have only getitem syntax

   - Season('AUTUMN')  # raises an exception
   - Season['AUTUMN']  # Season.AUTUMN


I'm not sure whether flufl.enums support creating additional instances after 
the event, but if it did, I would expect that I could say Season('WET') to get 
a new instance. I am indifferent to whether or not Season('AUTUMN') should 
return the existing AUTUMN enum value.

I think that I lean very slightly to these rules:

- Season(x) constructs new instances. If x is already a Season enum, it returns 
x; otherwise if x is a value already used for a Season enum, it raises.

- Season[x] looks up existing instances, and raises if x is not already a 
Season value.


but only very slightly.




Not only is this inconsistent with the rest of Python*, but it's going to be a 
PITA for data storage/retrieval:

 datastore = dbf.Table('storage.dbf', 'event_name C(50); date D; season 
SEASON')

 def retrieve_record(...):
 result = []
 for field_type, field_data in record:
 result.append(field_type(field_data))


Instead of having field_type be Season, couldn't you make it Season.__getitem__ 
?





--
Steven
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Stephen J. Turnbull
Steven D'Aprano writes:

  - should an enum item be selectable via __call__ instead of __getitem__
   (i.e. Seasons(3) is AUTUMN)
  
   No opinion.
  
  Does anyone know why this is even an issue? Is this pure
  bike-shedding over the API, or are there technical reasons for
  choosing one over the other?

Ethan thinks that Seasons(3) is a typecast, not an access into a
mapping (which would be better expressed by Seasons[3]).  Ie, the
inverse of int(AUTUMN).

This is consistent with the AUTUMN is-a Seasons position that Ethan
and Guido take.  It's inconsistent with the AUTUMN is-a
Seasons_VALUE implementation of Flufl.Enum.

@Ethan: I have real trouble sympathizing with your point of view
because you consistently pluralize your Enum names.  AUTUMN *is not* a
SeasonZZ, it is an element of the *collection* Seasons.  OTOH, AUTUMN
*is* a Season (look Ma, no ZZ!)  I wonder if you might not get more
sympathy from Guido if you named your Enums with the singular form.

Note that for some reason I don't have the same problem if Barry names
an Enum Season (no ZZ!)  I don't know why, maybe because the
semantics of type is to define a collection (which in English is
invariably denoted by the plural of the type name), so there's
implicitly a plural there.  But I'm not confident in that
psychoanalysis.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Ethan Furman

On 04/28/2013 07:10 PM, Stephen J. Turnbull wrote:


@Ethan: I have real trouble sympathizing with your point of view
because you consistently pluralize your Enum names.  AUTUMN *is not* a
SeasonZZ, it is an element of the *collection* Seasons.  OTOH, AUTUMN
*is* a Season (look Ma, no ZZ!)


I would hope that you would pay more attention to my arguments and rationale than to poorly chosen names.  The way 
English does things is not the only way things are done.


As it happens, I agree with you, and changed (and will change) all mention of Seasons to Season, and WeekDays to 
WeekDay, etc., etc., in my responses.


--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Ethan Furman

On 04/28/2013 06:52 PM, Steven D'Aprano wrote:

On 29/04/13 10:29, Ethan Furman wrote:

On 04/28/2013 04:37 PM, Steven D'Aprano wrote:

On Sun, Apr 28, 2013 at 12:32 PM, Ethan Furman et...@stoneleaf.us wrote:


   - should an enum item be selectable via __call__ instead of __getitem__
(i.e. Season(3) is AUTUMN)


Does anyone know why this is even an issue? Is this pure bike-shedding over the 
API, or are there
technical reasons for choosing one over the other?


This is an issue because currently every other type* in Python creates (or 
selects ;) its instances via the call syntax:

   - bool(1)# True
   - int('11')  # 11
   - str(var)   # whatever var had in it, now as a str


I think that's a red herring, because you're comparing the use of the object 
constructor with look-up by name.


int, float, and bool all have object constructors that take the given string and return a matching instance; int /may/ 
return a pre-existing instance, bool /will/ return a pre-existing instance.


As I've stated before, 'bool's are the closest existing data type to enums, in that bools use the object constructor to 
convert the incoming parameter to an existing bool instance, of which there will only ever be two.


bool(9) is bool('maybe') is bool(True) is True

and similarly, Enum behavior /should be/ (in my opinion ;)

Season.AUTUMN is Season('AUTUMN') is Season(3)

Like it or not, when you write `class Season(Enum)` a new *type* is created called Season, and Season(x) should either 
return a Season instance that matches x or raise.  Having a match and raising anyway just doesn't seem to me to be the 
Python Way.




But one of the latest changes to flufl.enum was to take out the call syntax, 
and have only getitem syntax

   - Season('AUTUMN')  # raises an exception
   - Season['AUTUMN']  # Season.AUTUMN


I'm not sure whether flufl.enums support creating additional instances after 
the event, but if it did, I would expect
that I could say Season('WET') to get a new instance. I am indifferent to 
whether or not Season('AUTUMN') should return
the existing AUTUMN enum value.


Adding more enumerators after the fact should not be supported; there is subclassing for that. Not worth actively 
preventing, but not encouraged.


--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Guido van Rossum
On Sun, Apr 28, 2013 at 3:28 PM, Nick Coghlan ncogh...@gmail.com wrote:
 Functions are descriptors, so this rule already covers ordinary methods. The
 slight concern I have with making the duck typed exclusion only descriptors
 (rather than descriptors and callables) is that it means things like
 functools.partial objects will be treated as enum values rather than as
 static methods. OTOH, explicitly wrapping such callables in staticmethod
 should still work, so the simpler rule is probably better.

I think the practice of using callables (other than possibly decorated
functions) as global variables is confusing at best, even in a
non-enum class, since few people will be able to predict whether they
will get the instance passed or not. So I think the rule looking only
for descriptors is superior.

There has been a whole lot more discussion in this thread. I am now
asking everyone to stop bikeshedding, even if you think *your* point
isn't bikeshedding -- the cacophony makes it impossible to hear
anyone.

There are a few more issues on which I'd like to pronounce.

1. The order in which iter(Color) should produce the items. The
argument has been made that definition order is the only order that is
not easily reconstructed, and I agree. So let's use definition order,
even if that means it can't be implemented in Python 2.

2. Whether Color(x) should be allowed, and what it should mean. Taking
the example of bool, it should return an existing enum if the argument
is either a Color or one of the values used for Color items (choosing
one somehow if there are multiple with the same value -- it doesn't
matter which one), and raise an exception if the argument is neither.
E.g.:

  class Color(Enum):
 red = 1
 white = 2
 blue = 3

x = Color.red
assert Color(x) is Color.red
assert Color(1) is Color.red
Color(42)  # raises

(2a. We could also allow Color('red') is Color.red, but that could be
confusing, and we can already do that with getattr(Color, 'red'), and
bool('False') doesn't return False anyway, so let's not do that.)

(2b. Let's not hypergeneralize and try to make bool and enums
completely alike. I see no advantage to adding bool.True and
bool.False, nor in making enums final classes, or giving a meaning
to iter(bool). Type bool is its own thing, but that doesn't mean enums
can't emulate aspects of it.)

Together with my pronouncements earlier in this thread I am hoping
that Eli and Barry will update the PEP and implementation (let's give
them a week) and everyone else will quiet down. I realize we're
deviating further from flufl.enum than our initial hope, but I think
the outcome is better.

--
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Stephen J. Turnbull
Ethan Furman writes:

  I would hope that you would pay more attention to my arguments and
  rationale than to poorly chosen names.

I do.  Nevertheless, it requires conscious effort.  It's quite
appropriate for you to ask that of me, but ... do you think you're
doing Python any good to ask more effort of Guido?  (Assuming he needs
it, of course -- I'm just conjecturing that the form of your examples
may make the whole thing less persuasive for him.  But of course he
has advantages, being Dutch and all :-)

  The way English does things is not the only way things are done.

I am nearly-native fluent in Japanese[1] -- I know better than most
people just how differently things *can* be done.  That doesn't help
much with the effort gradient in English, though.


Footnotes: 
[1]  Even my 15-year-old daughter admits that, so it must be true.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Ethan Furman

[re-directing back to python-dev]

On 04/28/2013 08:42 PM, Davis Silverman wrote:

as a not super experienced python developer, when i see Season('AUTUMN') it 
looks like im creating an a Season object. I
understand your resoning, that it acts like a boolean singleton, however, i 
feel it would confuse many, and isn't worth
it. From what i see, its meant to be a lookup sort of thing, but it doesnt 
really feel like one.

Or am i completely wrong about something?


As far as you are concerned, you are creating a Season object.  That it happens to be a pre-existing Season object is an 
implementation detail, and the whole thing would work just as well if it did indeed create a brand new object (you 
couldn't use `is` then, but in general `is` shouldn't be used anyway and I see no reason why `is` should be encouraged 
with Enums; use `==`).


Two examples:

  - the first few integers (up to 256 now, I think) are pre-created by the interpreter; when you do `int('7')` you are 
not getting a brand-new, never before used, integer 7 object, you're getting a cached integer 7 object.


  - all booleans (yup, both of them ;) are pre-created; when you ask for a True or a False, you are not getting a brand 
new one.


Since `is` is discouraged, both of those cases could go the other way (always creating a brand new object) and properly 
written programs would continue to run just fine -- slower, but fine.


Enums are the same: they could return brand new instances every time, and programs using `==` to compare will keep on 
working.  That they don't is an implementation detail.


The real guarantee with enums is that once you have one created you'll only 
ever see the original values; so

  class Last(Enum):
  X = 1
  Y = 2
  Z = 3

will only have three possible elements, X, Y, and Z, and X will always have the value of 1, Y will always have the vale 
of 2, and Z will always have the value of 3.  If you try and get `Last(W)` you'll trigger an exception, just like you 
do with `int(house)`.


--
~Ethan~
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Glenn Linderman

On 4/28/2013 9:09 PM, Guido van Rossum wrote:

(2a. We could also allow Color('red') is Color.red, but that could be
confusing, and we can already do that with getattr(Color, 'red'), and
bool('False') doesn't return False anyway, so let's not do that.)


Glad you made this pronouncement in this way, because otherwise there 
would be ambiguity in the case:


  class Color(Enum):
 red = 'white'
 white = 'blue'
 blue = 'red'

although that would no doubt drive the programmers batty anyway... but there 
may be instances where code is generated that could produce something 
ambiguous, even though this example is atrocious.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Guido van Rossum
On Sunday, April 28, 2013, Ethan Furman wrote:

 Enums are the same: they could return brand new instances every time, and
 programs using `==` to compare will keep on working.  That they don't is an
 implementation detail.


Whoa. In this case the identity property is not justban implementation
issue, it is part of the spec. Same for bool. (But == works too.)

--Guido


-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Georg Brandl
Am 28.04.2013 22:36, schrieb Ethan Furman:

 Example enumeration:
 
 class Seasons(Enum): SPRING = 1 SUMMER = 2 AUTUMN = 3 WINTER = 4
 
 days_in_year = 365
 
 @property def avg_temp(self): return (75, 92, 66, 33)[int(self)+1] #
 enums are 1-based
 
 
 Definite Issues:
 
 - should enum items be of the type of the Enum class? (i.e. type(SPRING) 
 is Seasons)
 
 IMO Yes.
 
 I agree.
 
 - should an enum item be selectable via __call__ instead of __getitem__ 
 (i.e. Seasons(3) is AUTUMN)
 
 No opinion.
 
 I think the callable syntax should be supported for database integration and
 consistency with every (?) other type in Python.  No opinion about the
 __getitem__ portion.
 
 
 - should days_in_year be enumerated?
 
 Yes. (If you don't want it to be, and it's not a method/descriptor, move it
 out of the class.)
 
 Making it a property to have it in the class certainly works for me.
 
 
 - should avg_temp be enumerated?
 
 IMO No.
 
 I agree.
 
 
 - for the above two, how should they be included/excluded?
 
 IMO Everything should be enumerated except (a) things with a __get__()
 method (i.e. descriptors) (b) __dunder__ names
 
 This also works for me.
 
 
 Also, I believe there's still an issue on the order in which items are 
 returned by iter(Seasons), but I don't know which way this is heading.
 
 As somebody pointed out earlier, the only order which cannot be reconstructed
 after the fact is definition order (value order can be, lexical order can be,
 etc.).  So my vote is to have the default iteration order be the original
 definition order, as any other desired order can be added to the class.

Thanks for the summary, that was very helpful.  I find myself agreeing with
every one of your opinions.  Good job :)

Georg


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] enum discussion: can someone please summarize open issues?

2013-04-28 Thread Steven D'Aprano
On Sun, Apr 28, 2013 at 09:02:15PM -0700, Ethan Furman wrote:

 Two examples:
 
   - the first few integers (up to 256 now, I think) are pre-created by the 
   interpreter; when you do `int('7')` you are not getting a brand-new, never 
 before used, integer 7 object, you're getting a cached integer 7 object.
 
   - all booleans (yup, both of them ;) are pre-created; when you ask for a 
   True or a False, you are not getting a brand new one.
 
 Since `is` is discouraged, both of those cases could go the other way 
 (always creating a brand new object) and properly written programs would 
 continue to run just fine -- slower, but fine.
 
 Enums are the same: they could return brand new instances every time, and 
 programs using `==` to compare will keep on working.  That they don't is an 
 implementation detail.

That's not how I understand it. I expected that the correct way to use 
enums is with identity checks:

if arg is Season.SUMMER: 
 handle_summer()


At least, that's how I'm used to dealing with sentinels or pseudo-enums 
created with object(), and I just expected it to carry over to actual 
enums. Should I reset my thinking and use == with flufl.enums?



-- 
Steven
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com