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


[Python-Dev] Enums and data retrieval

2013-04-29 Thread Ethan Furman

[starting new thread to not pollute the summary thread]

On 04/28/2013 11:54 PM, Antoine Pitrou wrote: 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?


The more specific context would be my dbf package, which works with dBase III, Clipper, and Foxpro tables.  When the 
fields of a record are requested they are transformed into Python data types, with code that looks pretty much like that 
retrieve_record snippet (w/o all the error checks, etc.).  And no, it doesn't support enumerations (yet).


A more general context would be anywhere that you need to convert the integer offset of an enum item back into the enum 
item itself; you may have gotten the integer offset from a postgres database, or an RPC call, and it seems to me the 
natural way get the enum item from that is with `EnumClass(offset)`.


--
~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 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] Enums and data retrieval

2013-04-29 Thread Antoine Pitrou
Le Mon, 29 Apr 2013 00:13:53 -0700,
Ethan Furman et...@stoneleaf.us a écrit :

 [starting new thread to not pollute the summary thread]
 
 On 04/28/2013 11:54 PM, Antoine Pitrou wrote: 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?
 
 The more specific context would be my dbf package, which works with
 dBase III, Clipper, and Foxpro tables.  When the fields of a record
 are requested they are transformed into Python data types, with code
 that looks pretty much like that retrieve_record snippet (w/o all the
 error checks, etc.).  And no, it doesn't support enumerations (yet).

Hmm, ok. So the context is the database adapter itself, right? I
wouldn't be shocked for a database adapter to have specific code to
handle various datatypes. My point was that this kind of code generally
doesn't leak into application code.

That said, I agree that the general constructor syntax should be
allowed on Enum instances. The inconsistency looks a bit gratuitous.

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


[Python-Dev] Purpose of files in $(DESTDIR)$(LIBPL)

2013-04-29 Thread Bohuslav Kabrda
Hi,
I'd like to ask about the purpose of files in $(DESTDIR)$(LIBPL) [1] - what is 
the reason to keep them/what are they useful for?
I'm currently taking over Python packaging in Fedora and I'd like to know if 
these have some meaning for a distro-packaged Python (Dave Malcolm is not sure 
about them ;)).

Thanks,
Slavek.

-- 
Regards,
Bohuslav Slavek Kabrda.

[1] http://hg.python.org/cpython/file/3.3/Makefile.pre.in#l1206
___
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


[Python-Dev] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Ethan Furman

[creating new thread]

On 04/29/2013 01:30 AM, Steven D'Aprano wrote:

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__



Words from Guido:

On 04/23/2013 08:11 AM, Guido van Rossum wrote:

I gotta say, I'm with Antoine here. It's pretty natural (also coming
from other languages) to assume that the class used to define the
enums is also the type of the enum values. Certainly this is how it
works in Java and C++, and I would say it's the same in Pascal and
probably most other languages.



On 04/25/2013 02:54 PM, Guido van Rossum wrote:

I don't know what's going on, but it feels like we had this same
discussion a week ago, and I still disagree. Disregarding, the C[i]
notation, I feel quite strongly that in the following example:

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

the values Color.red etc. should be instances of Color. This is how
things work in all other languages that I am aware of that let you
define enums.


On 04/25/2013 03:19 PM, Guido van Rossum wrote:

I suppose you were going to propose to use isinstance() overloading,
but I honestly think that Color.red.__class__ should be the same
object as Color.


On 04/25/2013 03:37 PM, Guido van Rossum wrote:

TBH I had a hard time getting over the fact that even though the class
said a = 1, C.a is not the integer 1. But I did get over it.
Hopefully you can get over *this* weirdness.


[and from the summary thread]

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

On Sun, Apr 28, 2013 at 12:32 PM, Ethan Furman wrote:


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


IMO Yes.

___
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] Destructors and Closing of File Objects

2013-04-29 Thread Armin Rigo
Hi Nikolaus,

On Sat, Apr 27, 2013 at 4:39 AM, Nikolaus Rath nikol...@rath.org wrote:
 It's indeed very informative, but it doesn't fully address the question
 because of the _pyio module which certainly can't use any custom C code.
 Does that mean that when I'm using x = _pyio.BufferedWriter(), I could loose
 data in the write buffer when the interpreter exits without me calling
 x.close(), but when using x = io.BufferedWriter(), the buffer is
 guaranteed to get flushed?

I actually described the behavior of CPython 2 while not realizing
that CPython 3 silently dropped this guarantee.  (I also never
realized that Jython/IronPython don't have the same guarantee; they
could, if they implement 'atexit', like we did in PyPy.  That's
however more acceptable if the platform itself doesn't offer the
guarantee.)

Anyway, it's a guarantee that the C offers, so personally I find it
reasonable to expect CPython files to offer it too; not offering it is
kind of saying that there is a feature of C that is actually present
at a higher level than the exact same feature in Python, which looks
backward to me.

Additionally, this might be introducing subtle bugs in programs when
porting them to Python 3.

However I realize that the two arguments presented above might not be
accepted as relevant.  (http://bugs.python.org/issue17852)


A bientôt,

Armin.
___
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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Adrian Sampson
On Apr 29, 2013, at 7:32 AM, Ethan Furman wrote:
 On 04/28/2013 01:02 PM, Guido van Rossum wrote:
 On Sun, Apr 28, 2013 at 12:32 PM, Ethan Furman wrote:
 - should enum items be of the type of the Enum class? (i.e. type(SPRING)
 is Seasons)

 IMO Yes.

This decision seems natural to me, so I wrote an enumeration library
some time ago that uses a simple metaclass to achieve
type(Season.spring) is Season:

https://github.com/sampsyo/beets/blob/master/beets/util/enumeration.py

The module has other warts but perhaps it can be helpful anyway.

Cheers,

Adrian

___
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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Guido van Rossum
Indeed, the type(Color.red) is Color claim was meant for the
situation where red is defined directly in Color, and I used type()
instead of isinstance() because Barry was proposing to overload
isinstance() to make this true without equating the classes. But for
the subclass case, I want MoreColor.red is Color.red and
isinstance(MoreColor.red, Color), but not isinstance(Color.red,
MoreColor). If you can't live with that, don't subclass enums.

On Mon, Apr 29, 2013 at 6:32 AM, Ethan Furman et...@stoneleaf.us wrote:
 [creating new thread]

 On 04/29/2013 01:30 AM, Steven D'Aprano wrote:

 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__



 Words from Guido:

 On 04/23/2013 08:11 AM, Guido van Rossum wrote:

 I gotta say, I'm with Antoine here. It's pretty natural (also coming
 from other languages) to assume that the class used to define the
 enums is also the type of the enum values. Certainly this is how it
 works in Java and C++, and I would say it's the same in Pascal and
 probably most other languages.


 On 04/25/2013 02:54 PM, Guido van Rossum wrote:

 I don't know what's going on, but it feels like we had this same
 discussion a week ago, and I still disagree. Disregarding, the C[i]
 notation, I feel quite strongly that in the following example:

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

 the values Color.red etc. should be instances of Color. This is how
 things work in all other languages that I am aware of that let you
 define enums.


 On 04/25/2013 03:19 PM, Guido van Rossum wrote:

 I suppose you were going to propose to use isinstance() overloading,
 but I honestly think that Color.red.__class__ should be the same
 object as Color.


 On 04/25/2013 03:37 PM, Guido van Rossum wrote:

 TBH I had a hard time getting over the fact that even though the class
 said a = 1, C.a is not the integer 1. But I did get over it.
 Hopefully you can get over *this* weirdness.


 [and from the summary thread]

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

 On Sun, Apr 28, 2013 at 12:32 PM, Ethan Furman wrote:


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


 IMO Yes.

 ___
 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] Destructors and Closing of File Objects

2013-04-29 Thread Antoine Pitrou
Le Mon, 29 Apr 2013 16:42:38 +0200,
Armin Rigo ar...@tunes.org a écrit :
 Hi Nikolaus,
 
 On Sat, Apr 27, 2013 at 4:39 AM, Nikolaus Rath nikol...@rath.org
 wrote:
  It's indeed very informative, but it doesn't fully address the
  question because of the _pyio module which certainly can't use any
  custom C code. Does that mean that when I'm using x =
  _pyio.BufferedWriter(), I could loose data in the write buffer when
  the interpreter exits without me calling x.close(), but when using
  x = io.BufferedWriter(), the buffer is guaranteed to get flushed?
 
 I actually described the behavior of CPython 2 while not realizing
 that CPython 3 silently dropped this guarantee.

It is dropped in the case of reference cycles, since there's no general
way to decide in which order the tp_clear calls have to be done.
Thus in the following layered situation: a TextIOWrapper on top of a
BufferedWriter on top of a FileIO, if BufferedWriter.tp_clear is called
first, it will flush and then close itself, closing the FileIO at the
same time, and when TextIOWrapper.tp_clear will be called it will be
too late to flush its own buffer.

(I have to investigate a bit to confirm it is what happens)

I will try to think of a scheme to make flushing more reliable, but
nothing springs to my mind right now.

Note that the issue of how reference cycles involving globals are
collected at interpreter shutdown is an orthogonal one, as pointed out
in http://bugs.python.org/issue17852.

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 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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Ethan Furman

On 04/29/2013 08:39 AM, Guido van Rossum wrote:

Indeed, the type(Color.red) is Color claim was meant for the
situation where red is defined directly in Color, and I used type()
instead of isinstance() because Barry was proposing to overload
isinstance() to make this true without equating the classes. But for
the subclass case, I want MoreColor.red is Color.red and
isinstance(MoreColor.red, Color), but not isinstance(Color.red,
MoreColor). If you can't live with that, don't subclass enums.


So if I understand:

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

-- class MoreColor(Color):
... cyan = 4
... magenta = 5
... yellow = 6

-- type(MoreColor.red) is Color

-- type(MoreColor.red) is not MoreColor

In other words, while `red` is accessible in MoreColor, it's actually a Color 
instance?

--
~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 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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

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

 Indeed, the type(Color.red) is Color claim was meant for the
 situation where red is defined directly in Color, and I used type()
 instead of isinstance() because Barry was proposing to overload
 isinstance() to make this true without equating the classes. But for
 the subclass case, I want MoreColor.red is Color.red and
 isinstance(MoreColor.red, Color), but not isinstance(Color.red,
 MoreColor). If you can't live with that, don't subclass enums.


 So if I understand:

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

 -- class MoreColor(Color):
 ... cyan = 4
 ... magenta = 5
 ... yellow = 6

 -- type(MoreColor.red) is Color

 -- type(MoreColor.red) is not MoreColor

 In other words, while `red` is accessible in MoreColor, it's actually a
 Color instance?

Oh dear, this is actually a mess. I don't want MoreColor.red and
Color.red to be distinct objects, but then the isinstance() checks
will become confusing. If we don't override isinstance(), we'll get

  not isinstance(Color.red, MoreColor)
  isinstance(MoreColor.yellow, Color)

This would be pretty backwards.

I Ggoogled enum subclassing and found this StackOverflow article
explaining why you can't subclass enums in Java:
http://stackoverflow.com/questions/4604978/subclassing-an-enum which
refers to this more elaborate answer:
http://stackoverflow.com/questions/3427947/enumeration-inheritence-in-java/3428050#3428050

I think this conclusively shows that it's better to disallow
subclassing enums. (It also brings enum in line with bool, which is
also a final class.)

Adding Eli to the thread explicitly, because this needs to be
explained in the PEP.

--
--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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Glenn Linderman

On 4/29/2013 10:01 AM, Guido van Rossum wrote:

On Mon, Apr 29, 2013 at 9:12 AM, Ethan Furman et...@stoneleaf.us wrote:

On 04/29/2013 08:39 AM, Guido van Rossum wrote:

Indeed, the type(Color.red) is Color claim was meant for the
situation where red is defined directly in Color, and I used type()
instead of isinstance() because Barry was proposing to overload
isinstance() to make this true without equating the classes. But for
the subclass case, I want MoreColor.red is Color.red and
isinstance(MoreColor.red, Color), but not isinstance(Color.red,
MoreColor). If you can't live with that, don't subclass enums.


So if I understand:

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

-- class MoreColor(Color):
... cyan = 4
... magenta = 5
... yellow = 6

-- type(MoreColor.red) is Color

-- type(MoreColor.red) is not MoreColor

In other words, while `red` is accessible in MoreColor, it's actually a
Color instance?

Oh dear, this is actually a mess. I don't want MoreColor.red and
Color.red to be distinct objects, but then the isinstance() checks
will become confusing. If we don't override isinstance(), we'll get

   not isinstance(Color.red, MoreColor)
   isinstance(MoreColor.yellow, Color)

This would be pretty backwards.

I Ggoogled enum subclassing and found this StackOverflow article
explaining why you can't subclass enums in Java:
http://stackoverflow.com/questions/4604978/subclassing-an-enum which
refers to this more elaborate answer:
http://stackoverflow.com/questions/3427947/enumeration-inheritence-in-java/3428050#3428050

I think this conclusively shows that it's better to disallow
subclassing enums. (It also brings enum in line with bool, which is
also a final class.)

Adding Eli to the thread explicitly, because this needs to be
explained in the PEP.


The only thing that needs to be disallowed is defining additional named 
elements, for Liskov Substitution to not be violated.


So in an inheritance tree derived from Enum, it would be a requirement 
that all members of the enumeration be enumerated in one class.


It would be extremely nice if:

1) Enum could be subclassed to provide different, sharable, types of 
behaviors, then further subclassed to provide a number of distinct sets 
of values with those behaviors.


2) Enum could be subclassed to provide one set of values, and then 
further subclassed to provide a number a distinct sets of behaviors for 
those sets of values.


(I see a lot more benefit to #1, than #2, if a choice must be made.)
___
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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Steven D'Aprano

On 30/04/13 03:01, Guido van Rossum wrote:


Oh dear, this is actually a mess. I don't want MoreColor.red and
Color.red to be distinct objects, but then the isinstance() checks
will become confusing. If we don't override isinstance(), we'll get

   not isinstance(Color.red, MoreColor)
   isinstance(MoreColor.yellow, Color)

This would be pretty backwards.


Why is that backwards? MoreColor is a subclass of Color, so instances of 
MoreColor are instances of Color, but instances of Color are not instances of 
MoreColor. That's normal behaviour for subclasses. (All cats are mammals, but 
not all mammals are cats.)

The only funny thing about this is that enumeration values of a Enum are only 
instances of that Enum if they are declared inside that Enum, and as far as I'm concerned 
that's not especially funny at all. So:

Color declares red, so Color.red is a Color.

MoreColor does not declare red, it merely inherits it from Color, so 
MoreColor.red is Color.red which is not a MoreColor.


This leads to a simple rule:

Enum values are either instances of the enum they are defined in, or instances 
of the parent class they are inherited from.

If the user doesn't like that, they're free to not subclass Enums :-)




I Ggoogled enum subclassing and found this StackOverflow article
explaining why you can't subclass enums in Java:
http://stackoverflow.com/questions/4604978/subclassing-an-enum which
refers to this more elaborate answer:
http://stackoverflow.com/questions/3427947/enumeration-inheritence-in-java/3428050#3428050


The first link says:

And generally, a proper subclass is a specialization of its superclass.

and gives the Liskov Substitution Principle as the reason for prohibiting 
subclassing. LSP is a very useful principle, but it is not the only model for 
subclassing. That's why it's called a *principle* and not the Liskov 
Substitution *Law*.

(Yes, I stole that from Raymond Hettinger's talk on subclassing at PyCon.)

I think that the ability to extend enums with new ones, without duplicating 
code, is more important for enums than satisfying LSP. The common use-cases for 
enums do not lend itself to subtyping in the Liskov sense.

E.g. if I have a function that expects a Color red/blue/green enum, and I 
subclass it to give MoreColor yellow, I can't expect the function to suddenly 
recognise yellow. So I'm not going to use subclassing in this case, because it 
can't work.

But I will use subclassing to reuse values: if I have a function that expects 
red/blue/green/yellow, and red/blue/green are already defined in Color, I'll 
want to reuse them rather than duplicate them. Hence I will subclass Color 
specifically to extend it, not to specialise it.


The second link quotes:

For the most part, extensibility of enums turns out to be a bad idea. It is 
confusing that elements of an extension type are instances of the base type and not vice 
versa.

Confusing for who, and why?

You're going to confuse *somebody* no matter what you do. Either:

- confuse people who try to subclass enums, and can't; or

- confuse people who try to subclass enums, and can, but then get confused by 
the result.





--
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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Guido van Rossum
You are too verbose. I have already said what I needed to say.

On Mon, Apr 29, 2013 at 11:24 AM, Steven D'Aprano st...@pearwood.info wrote:
 On 30/04/13 03:01, Guido van Rossum wrote:

 Oh dear, this is actually a mess. I don't want MoreColor.red and
 Color.red to be distinct objects, but then the isinstance() checks
 will become confusing. If we don't override isinstance(), we'll get

not isinstance(Color.red, MoreColor)
isinstance(MoreColor.yellow, Color)

 This would be pretty backwards.


 Why is that backwards? MoreColor is a subclass of Color, so instances of
 MoreColor are instances of Color, but instances of Color are not instances
 of MoreColor. That's normal behaviour for subclasses. (All cats are mammals,
 but not all mammals are cats.)

 The only funny thing about this is that enumeration values of a Enum are
 only instances of that Enum if they are declared inside that Enum, and as
 far as I'm concerned that's not especially funny at all. So:

 Color declares red, so Color.red is a Color.

 MoreColor does not declare red, it merely inherits it from Color, so
 MoreColor.red is Color.red which is not a MoreColor.


 This leads to a simple rule:

 Enum values are either instances of the enum they are defined in, or
 instances of the parent class they are inherited from.

 If the user doesn't like that, they're free to not subclass Enums :-)




 I Ggoogled enum subclassing and found this StackOverflow article
 explaining why you can't subclass enums in Java:
 http://stackoverflow.com/questions/4604978/subclassing-an-enum which
 refers to this more elaborate answer:

 http://stackoverflow.com/questions/3427947/enumeration-inheritence-in-java/3428050#3428050


 The first link says:

 And generally, a proper subclass is a specialization of its superclass.

 and gives the Liskov Substitution Principle as the reason for prohibiting
 subclassing. LSP is a very useful principle, but it is not the only model
 for subclassing. That's why it's called a *principle* and not the Liskov
 Substitution *Law*.

 (Yes, I stole that from Raymond Hettinger's talk on subclassing at PyCon.)

 I think that the ability to extend enums with new ones, without duplicating
 code, is more important for enums than satisfying LSP. The common use-cases
 for enums do not lend itself to subtyping in the Liskov sense.

 E.g. if I have a function that expects a Color red/blue/green enum, and I
 subclass it to give MoreColor yellow, I can't expect the function to
 suddenly recognise yellow. So I'm not going to use subclassing in this case,
 because it can't work.

 But I will use subclassing to reuse values: if I have a function that
 expects red/blue/green/yellow, and red/blue/green are already defined in
 Color, I'll want to reuse them rather than duplicate them. Hence I will
 subclass Color specifically to extend it, not to specialise it.


 The second link quotes:

 For the most part, extensibility of enums turns out to be a bad idea. It is
 confusing that elements of an extension type are instances of the base type
 and not vice versa.

 Confusing for who, and why?

 You're going to confuse *somebody* no matter what you do. Either:

 - confuse people who try to subclass enums, and can't; or

 - confuse people who try to subclass enums, and can, but then get confused
 by the result.





 --
 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/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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Larry Hastings

On 04/29/2013 10:01 AM, Guido van Rossum wrote:

On Mon, Apr 29, 2013 at 9:12 AM, Ethan Furman et...@stoneleaf.us wrote:

On 04/29/2013 08:39 AM, Guido van Rossum wrote:

Indeed, the type(Color.red) is Color claim was meant for the
situation where red is defined directly in Color, and I used type()
instead of isinstance() because Barry was proposing to overload
isinstance() to make this true without equating the classes. But for
the subclass case, I want MoreColor.red is Color.red and
isinstance(MoreColor.red, Color), but not isinstance(Color.red,
MoreColor). If you can't live with that, don't subclass enums.


So if I understand:

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

-- class MoreColor(Color):
... cyan = 4
... magenta = 5
... yellow = 6

-- type(MoreColor.red) is Color

-- type(MoreColor.red) is not MoreColor

In other words, while `red` is accessible in MoreColor, it's actually a
Color instance?

Oh dear, this is actually a mess. I don't want MoreColor.red and
Color.red to be distinct objects, but then the isinstance() checks
will become confusing. If we don't override isinstance(), we'll get

   not isinstance(Color.red, MoreColor)
   isinstance(MoreColor.yellow, Color)

This would be pretty backwards.


What's the problem with overriding the isinstance checks?  You mention 
it but seem to assume it's a bad idea.  That seems to me like it'd 
adequately solve that problem with an acceptable level of magic.



//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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread MRAB

On 29/04/2013 19:24, Steven D'Aprano wrote:

On 30/04/13 03:01, Guido van Rossum wrote:


Oh dear, this is actually a mess. I don't want MoreColor.red and
Color.red to be distinct objects, but then the isinstance() checks
will become confusing. If we don't override isinstance(), we'll
get

not isinstance(Color.red, MoreColor) isinstance(MoreColor.yellow,
Color)

This would be pretty backwards.


Why is that backwards? MoreColor is a subclass of Color, so instances
of MoreColor are instances of Color, but instances of Color are not
instances of MoreColor. That's normal behaviour for subclasses. (All
cats are mammals, but not all mammals are cats.)


Let's say that Color is red, green, or blue.

Let's also say that MoreColor is superset of Color, in other words, any
of Color, plus cyan, magenta, or yellow.

Red is a Color and a MoreColor (member of Color and MoreColor).

Yellow is a MoreColor, but not a Color (member of MoreColor but not
Color).

That's the opposite of the rules of inheritance.


The only funny thing about this is that enumeration values of a
Enum are only instances of that Enum if they are declared inside that
Enum, and as far as I'm concerned that's not especially funny at all.
So:

Color declares red, so Color.red is a Color.

MoreColor does not declare red, it merely inherits it from Color, so
MoreColor.red is Color.red which is not a MoreColor.


This leads to a simple rule:

Enum values are either instances of the enum they are defined in, or
instances of the parent class they are inherited from.

If the user doesn't like that, they're free to not subclass Enums
:-)




I Ggoogled enum subclassing and found this StackOverflow article
explaining why you can't subclass enums in Java:
http://stackoverflow.com/questions/4604978/subclassing-an-enum
which refers to this more elaborate answer:
http://stackoverflow.com/questions/3427947/enumeration-inheritence-in-java/3428050#3428050





The first link says:

And generally, a proper subclass is a specialization of its
superclass.

and gives the Liskov Substitution Principle as the reason for
prohibiting subclassing. LSP is a very useful principle, but it is
not the only model for subclassing. That's why it's called a
*principle* and not the Liskov Substitution *Law*.

(Yes, I stole that from Raymond Hettinger's talk on subclassing at
PyCon.)

I think that the ability to extend enums with new ones, without
duplicating code, is more important for enums than satisfying LSP.
The common use-cases for enums do not lend itself to subtyping in the
Liskov sense.

E.g. if I have a function that expects a Color red/blue/green enum,
and I subclass it to give MoreColor yellow, I can't expect the
function to suddenly recognise yellow. So I'm not going to use
subclassing in this case, because it can't work.

But I will use subclassing to reuse values: if I have a function that
expects red/blue/green/yellow, and red/blue/green are already defined
in Color, I'll want to reuse them rather than duplicate them. Hence I
will subclass Color specifically to extend it, not to specialise it.


On the other hand, a function that expects MoreColor should also accept
Color, which is a subset.



The second link quotes:

For the most part, extensibility of enums turns out to be a bad
idea. It is confusing that elements of an extension type are
instances of the base type and not vice versa.

Confusing for who, and why?

You're going to confuse *somebody* no matter what you do. Either:

- confuse people who try to subclass enums, and can't; or

- confuse people who try to subclass enums, and can, but then get
confused by the result.


___
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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Guido van Rossum
On Mon, Apr 29, 2013 at 11:34 AM, Larry Hastings la...@hastings.org wrote:
 What's the problem with overriding the isinstance checks?  You mention it
 but seem to assume it's a bad idea.  That seems to me like it'd adequately
 solve that problem with an acceptable level of magic.

Depending on whether you are using isinstance() to check if an enum
value belongs in the set of acceptable enums, or to check it it makes
sense to call a certain method, you need isinstance() to behave
differently.

In particular, the default isinstance() would correctly state that
MoreColor.red is not a MoreColor instance, so any methods defined only
on MoreColor should not be called. OTOH it gives the wrong answer if
you are checking that Color.red is an acceptable MoreColor value. But
if you override isinstance() to give the right answer for the latter
(so isinstance(Color.red, MoreColor) is True), then you could
incorrectly conclude that it is safe to call a MoreColor method on
Color.red.

Please do read the StackOverflow links I gave:

http://stackoverflow.com/questions/4604978/subclassing-an-enum
http://stackoverflow.com/questions/3427947/enumeration-inheritence-in-java/3428050#3428050

--
--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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Serhiy Storchaka

29.04.13 21:14, Glenn Linderman написав(ла):

1) Enum could be subclassed to provide different, sharable, types of
behaviors, then further subclassed to provide a number of distinct sets
of values with those behaviors.


You can use a multiclass inheritance for this.


2) Enum could be subclassed to provide one set of values, and then
further subclassed to provide a number a distinct sets of behaviors for
those sets of values.


How is it possible? You haven't any instance of subclass.


___
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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Steven D'Aprano

On 30/04/13 04:29, Guido van Rossum wrote:

You are too verbose. I have already said what I needed to say.


Sorry about that, sometimes I do go on and on. Let me be more terse.

When it comes to enums, I believe that violating Liskov is a feature, not a bug.

Also, I understand that both Scala and Kotlin allow subclassing enums in 
exactly the way we're talking about.


--
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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Oscar Benjamin
On 29 April 2013 20:04, Guido van Rossum gu...@python.org wrote:
 On Mon, Apr 29, 2013 at 11:34 AM, Larry Hastings la...@hastings.org wrote:
 What's the problem with overriding the isinstance checks?  You mention it
 but seem to assume it's a bad idea.  That seems to me like it'd adequately
 solve that problem with an acceptable level of magic.

 Depending on whether you are using isinstance() to check if an enum
 value belongs in the set of acceptable enums, or to check it it makes
 sense to call a certain method, you need isinstance() to behave
 differently.

Would it not be better to avoid using isinstance() for this?

I would have expected membership testing to use Red in Colors rather
than isinstance(Red, Color) like in this stackoverflow question
about an enum class:
http://stackoverflow.com/questions/10445819/overriding-contains-method-for-a-class


Oscar
___
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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Steven D'Aprano

On 30/04/13 05:02, MRAB wrote:


Why is that backwards? MoreColor is a subclass of Color, so instances
of MoreColor are instances of Color, but instances of Color are not
instances of MoreColor. That's normal behaviour for subclasses. (All
cats are mammals, but not all mammals are cats.)


Let's say that Color is red, green, or blue.

Let's also say that MoreColor is superset of Color, in other words, any
of Color, plus cyan, magenta, or yellow.

Red is a Color and a MoreColor (member of Color and MoreColor).

Yellow is a MoreColor, but not a Color (member of MoreColor but not
Color).

That's the opposite of the rules of inheritance.


Membership != inheritance, you are conflating two independent concepts. I would expect 
that for membership testing, you should say value in MoreColor, not 
isinstance(value, MoreColor).

flufl.enum has been in use for Mailman for many years, and I would like to hear 
Barry's opinion on this.



--
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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread Guido van Rossum
On Mon, Apr 29, 2013 at 12:52 PM, Oscar Benjamin
oscar.j.benja...@gmail.com wrote:
 Would it not be better to avoid using isinstance() for this?

In a recent thread I explained why using isinstance() is important.
It's how we check for every other type, and it would be awlward for
type-checking frameworks to have to special-case enums. (When we're
not using duck typing.)

--
--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 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] Purpose of files in $(DESTDIR)$(LIBPL)

2013-04-29 Thread Ned Deily
In article 1100748677.3355198.1367227656892.javamail.r...@redhat.com,
 Bohuslav Kabrda bkab...@redhat.com wrote:
 I'd like to ask about the purpose of files in $(DESTDIR)$(LIBPL) [1] - what 
 is the reason to keep them/what are they useful for?
 I'm currently taking over Python packaging in Fedora and I'd like to know 
 if these have some meaning for a distro-packaged Python (Dave Malcolm is not 
 sure about them ;)).

As is noted a bit further up in Makefile.pre.in:

  1178 # Install the library and miscellaneous stuff needed for 
extending/embedding
  1179 # This goes into $(exec_prefix)
  1180 LIBPL= $(LIBDEST)/config-$(LDVERSION)

As I understand it, LIBPL is the directory that contains the development 
files needed for embedding Python in C, things like the static and 
shared libpythox.x and the Makefile itself.  They are intended to be 
referenced through the pythonx.y-config command.  For example, on 
Debian,  LIBPL is /usr/lib/python2.7/config.

$ python2.7-config --ldflags
-L/usr/lib/python2.7/config -lpthread -ldl -lutil -lm -lpython2.7 
-Xlinker -export-dynamic

The usage is documented here:

http://docs.python.org/dev/extending/embedding.html#compiling-and-linking
-under-unix-like-systems

-- 
 Ned Deily,
 n...@acm.org

___
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] Enumeration item arguments?

2013-04-29 Thread Ethan Furman

In the Planet example we saw the possibility of specifying arguments to enum 
item __init__:

class Planet(Enum):
MERCURY = (3.303e+23, 2.4397e6)
VENUS   = (4.869e+24, 6.0518e6)
EARTH   = (5.976e+24, 6.37814e6)
MARS= (6.421e+23, 3.3972e6)
JUPITER = (1.9e+27,   7.1492e7)
SATURN  = (5.688e+26, 6.0268e7)
URANUS  = (8.686e+25, 2.5559e7)
NEPTUNE = (1.024e+26, 2.4746e7)

def __init__(self, mass, radius):
self.mass = mass   # in kilograms
self.radius = radius   # in meters

Do we want to support this?

--
~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] Enumeration item arguments?

2013-04-29 Thread Serhiy Storchaka

30.04.13 00:59, Ethan Furman написав(ла):

In the Planet example we saw the possibility of specifying arguments to
enum item __init__:

class Planet(Enum):
 MERCURY = (3.303e+23, 2.4397e6)
 VENUS   = (4.869e+24, 6.0518e6)
 EARTH   = (5.976e+24, 6.37814e6)
 MARS= (6.421e+23, 3.3972e6)
 JUPITER = (1.9e+27,   7.1492e7)
 SATURN  = (5.688e+26, 6.0268e7)
 URANUS  = (8.686e+25, 2.5559e7)
 NEPTUNE = (1.024e+26, 2.4746e7)

 def __init__(self, mass, radius):
 self.mass = mass   # in kilograms
 self.radius = radius   # in meters


It should have different signature as Larry proposed:

 def __init__(self, value):
 self.mass, self.radius = *value



___
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] Enumeration item arguments?

2013-04-29 Thread Guido van Rossum
Only if it is easy to implement. This example doesn't look like a good
fit for enums, but if the enum implementation can easily support this
(e.g. if there's nothing special about __init__) I don't want to
forcibly rule it out. I don't want to have to bend over backwards to
support it, however, if it causes problems for the implementation.

On Mon, Apr 29, 2013 at 2:59 PM, Ethan Furman et...@stoneleaf.us wrote:
 In the Planet example we saw the possibility of specifying arguments to enum
 item __init__:

 class Planet(Enum):
 MERCURY = (3.303e+23, 2.4397e6)
 VENUS   = (4.869e+24, 6.0518e6)
 EARTH   = (5.976e+24, 6.37814e6)
 MARS= (6.421e+23, 3.3972e6)
 JUPITER = (1.9e+27,   7.1492e7)
 SATURN  = (5.688e+26, 6.0268e7)
 URANUS  = (8.686e+25, 2.5559e7)
 NEPTUNE = (1.024e+26, 2.4746e7)

 def __init__(self, mass, radius):
 self.mass = mass   # in kilograms
 self.radius = radius   # in meters

 Do we want to support this?

 --
 ~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/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-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


Re: [Python-Dev] Enumeration item arguments?

2013-04-29 Thread Eli Bendersky
On Mon, Apr 29, 2013 at 2:59 PM, Ethan Furman et...@stoneleaf.us wrote:

 In the Planet example we saw the possibility of specifying arguments to
 enum item __init__:

 class Planet(Enum):
 MERCURY = (3.303e+23, 2.4397e6)
 VENUS   = (4.869e+24, 6.0518e6)
 EARTH   = (5.976e+24, 6.37814e6)
 MARS= (6.421e+23, 3.3972e6)
 JUPITER = (1.9e+27,   7.1492e7)
 SATURN  = (5.688e+26, 6.0268e7)
 URANUS  = (8.686e+25, 2.5559e7)
 NEPTUNE = (1.024e+26, 2.4746e7)

 def __init__(self, mass, radius):
 self.mass = mass   # in kilograms
 self.radius = radius   # in meters

 Do we want to support this?


I'm -1, and this is yet another bad sign of conflating enums with classes.
If planets want to have attributes and behaviors, let them be normal
classes. If they want a PlanetId *enum member*, that's OK, but there's no
need to intermix the two.

Besides, did we not agree that the only acceptable *members* for enums are
going to be descriptors? In the above, mass  radius are not descriptors.

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] Enumeration item arguments?

2013-04-29 Thread Ethan Furman

On 04/29/2013 03:25 PM, Eli Bendersky wrote:

On Mon, Apr 29, 2013 at 2:59 PM, Ethan Furman wrote:


In the Planet example we saw the possibility of specifying arguments to enum 
item __init__:

class Planet(Enum):
 MERCURY = (3.303e+23, 2.4397e6)
 VENUS   = (4.869e+24, 6.0518e6)
 EARTH   = (5.976e+24, 6.37814e6)
 MARS= (6.421e+23, 3.3972e6)
 JUPITER = (1.9e+27,   7.1492e7)
 SATURN  = (5.688e+26, 6.0268e7)
 URANUS  = (8.686e+25, 2.5559e7)
 NEPTUNE = (1.024e+26, 2.4746e7)

 def __init__(self, mass, radius):
 self.mass = mass   # in kilograms
 self.radius = radius   # in meters

Do we want to support this?


I'm -1, and this is yet another bad sign of conflating enums with classes. If 
planets want to have attributes and
behaviors, let them be normal classes. If they want a PlanetId *enum member*, 
that's OK, but there's no need to intermix
the two.

Besides, did we not agree that the only acceptable *members* for enums are going to 
be descriptors? In the above, mass 
radius are not descriptors.


Good point. We can leave that out, then.

--
~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] Enumeration item arguments?

2013-04-29 Thread Ethan Furman

On 04/29/2013 03:13 PM, Guido van Rossum wrote:

Only if it is easy to implement. This example doesn't look like a good
fit for enums, but if the enum implementation can easily support this
(e.g. if there's nothing special about __init__) I don't want to
forcibly rule it out. I don't want to have to bend over backwards to
support it, however, if it causes problems for the implementation.


Beautiful answer.  :)

--
~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


[Python-Dev] Enumeration items: mixed types?

2013-04-29 Thread Ethan Furman

This just doesn't make sense to me:

-- class Stuff(Enum):
... blue = 1
... china = 'really big country'
... random = (8273.199, 517)

-- Stuff.blue.name == 'blue'
-- Stuff.blue.value == 1

-- Stuff.china.name == 'china'
-- Stuff.china.value == ???

-- Stuff.random.name == 'random'
-- Stuff.china.value == ???

In order to make this work at all, we have to support auto-numbering, and I didn't think we were going to do that in the 
class syntax?


--
~Ethan~

P.S.  Apologies for all the questions, I'm just hoping to get the last details hammered out so we can stop discussing 
Enums.  ;)

___
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] Enumeration item arguments?

2013-04-29 Thread Larry Hastings

On 04/29/2013 03:33 PM, Ethan Furman wrote:

On 04/29/2013 03:25 PM, Eli Bendersky wrote:

On Mon, Apr 29, 2013 at 2:59 PM, Ethan Furman wrote:


In the Planet example we saw the possibility of specifying arguments 
to enum item __init__:


class Planet(Enum):
 MERCURY = (3.303e+23, 2.4397e6)
 VENUS   = (4.869e+24, 6.0518e6)
 EARTH   = (5.976e+24, 6.37814e6)
 MARS= (6.421e+23, 3.3972e6)
 JUPITER = (1.9e+27,   7.1492e7)
 SATURN  = (5.688e+26, 6.0268e7)
 URANUS  = (8.686e+25, 2.5559e7)
 NEPTUNE = (1.024e+26, 2.4746e7)

 def __init__(self, mass, radius):
 self.mass = mass   # in kilograms
 self.radius = radius   # in meters

Do we want to support this?


Besides, did we not agree that the only acceptable *members* for 
enums are going to be descriptors? In the above, mass 

radius are not descriptors.

Good point. We can leave that out, then.


self.__mass = mass

And surely we were discussing members of the class, not members of 
instances.



//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] Enumeration items: `type(EnumClass.item) is EnumClass` ?

2013-04-29 Thread MRAB

On 29/04/2013 21:00, Steven D'Aprano wrote:

On 30/04/13 05:02, MRAB wrote:


Why is that backwards? MoreColor is a subclass of Color, so
instances of MoreColor are instances of Color, but instances of
Color are not instances of MoreColor. That's normal behaviour for
subclasses. (All cats are mammals, but not all mammals are
cats.)


Let's say that Color is red, green, or blue.

Let's also say that MoreColor is superset of Color, in other words,
any of Color, plus cyan, magenta, or yellow.

Red is a Color and a MoreColor (member of Color and MoreColor).

Yellow is a MoreColor, but not a Color (member of MoreColor but
not Color).

That's the opposite of the rules of inheritance.


Membership != inheritance, you are conflating two independent
concepts. I would expect that for membership testing, you should say
value in MoreColor, not isinstance(value, MoreColor).


I do know the difference, but it's not helpful that you're creating the
enum with a class statement!


flufl.enum has been in use for Mailman for many years, and I would
like to hear Barry's opinion on this.


___
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] Enumeration item arguments?

2013-04-29 Thread Ethan Furman

On 04/29/2013 03:25 PM, Eli Bendersky wrote:


Besides, did we not agree that the only acceptable *members* for enums are going to 
be descriptors? In the above, mass 
radius are not descriptors.


Actually, it's the other way -- descriptors are excluded from being enum items, 
along  with dunders.

--
~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] Enumeration items: mixed types?

2013-04-29 Thread Ethan Furman

On 04/29/2013 03:50 PM, Ethan Furman wrote:

This just doesn't make sense to me:

-- class Stuff(Enum):
... blue = 1
... china = 'really big country'
... random = (8273.199, 517)

-- Stuff.blue.name == 'blue'
-- Stuff.blue.value == 1

-- Stuff.china.name == 'china'
-- Stuff.china.value == ???

-- Stuff.random.name == 'random'
-- Stuff.china.value == ???

In order to make this work at all, we have to support auto-numbering, and I 
didn't think we were going to do that in the
class syntax?


I suppose the other option is to have `.value` be whatever was assigned (1, 'really big country', and (8273.199, 517) ), 
and the fact that `int(Stuff.china) ` blows up and doesn't store easily in a database is the programmers issue...


--
~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] Destructors and Closing of File Objects

2013-04-29 Thread Jeff Allen

On 29/04/2013 15:42, Armin Rigo wrote:

On Sat, Apr 27, 2013 at 4:39 AM, Nikolaus Rath nikol...@rath.org wrote:

It's indeed very informative, but it doesn't fully address the question
because of the _pyio module which certainly can't use any custom C code.
Does that mean that when I'm using x = _pyio.BufferedWriter(), I could loose
data in the write buffer when the interpreter exits without me calling
x.close(), but when using x = io.BufferedWriter(), the buffer is
guaranteed to get flushed?

I actually described the behavior of CPython 2 while not realizing
that CPython 3 silently dropped this guarantee.  (I also never
realized that Jython/IronPython don't have the same guarantee; they
could, if they implement 'atexit', like we did in PyPy.

On 29/04/2013 17:02, Antoine Pitrou wrote:

It is dropped in the case of reference cycles, since there's no general
way to decide in which order the tp_clear calls have to be done.
Thus in the following layered situation: a TextIOWrapper on top of a
BufferedWriter on top of a FileIO, if BufferedWriter.tp_clear is called
first, it will flush and then close itself, closing the FileIO at the
same time, and when TextIOWrapper.tp_clear will be called it will be
too late to flush its own buffer.

(I have to investigate a bit to confirm it is what happens)

I will try to think of a scheme to make flushing more reliable, but
nothing springs to my mind right now.

In Jython, objects are not cleared immediately they become unreachable 
and if the JVM does not collect them before it shuts down, no programmed 
finalization may be called. To get round this, files in need of closing 
are hooked to a list that is worked off as the JVM shuts down, the 
equivalent of atexit (I assume). It has the unfortunate effect that 
forgotten files may live even longer, making it even more desirable that 
the user remember to close them. (The io tests themselves are not good 
at this!) But at least the close comes eventually.


After discussion on jython-dev, I recently changed this mechanism 
(aiming at v2.7) so that every layer e.g. TextIOWrapper, BufferedWriter, 
FileIO is separately hooked to the list, and these are closed in reverse 
order of creation. Since close invokes flush when it matters, this will 
nearly always mean data is flushed down the stack before the path to 
disk gets severed, and always if you used open() to create the stack. I 
couldn't think of a perfect solution that didn't mean change to the API.


This idea, and some tidying up I did in the io tests, might be of use in 
CPython.


Jeff
___
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] Enumeration item arguments?

2013-04-29 Thread Greg Ewing

Eli Bendersky wrote:
Besides, did we not agree that the only acceptable *members* for enums 
are going to be descriptors?


No, that only applies to names assigned in the class body.
Here, mass and radius are being set a different way, so
there is no restriction on them.

--
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] Enumeration items: mixed types?

2013-04-29 Thread Greg Ewing

Ethan Furman wrote:
I suppose the other option is to have `.value` be whatever was assigned 
(1, 'really big country', and (8273.199, 517) ),


I thought that was the intention all along, and that we'd
given up on the idea of auto-assigning integer values
(because it would require either new syntax or extremely
dark magic).

--
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] Destructors and Closing of File Objects

2013-04-29 Thread Nikolaus Rath
Armin Rigo ar...@tunes.org writes:
 Hi Nikolaus,

 On Sat, Apr 27, 2013 at 4:39 AM, Nikolaus Rath nikol...@rath.org wrote:
 It's indeed very informative, but it doesn't fully address the question
 because of the _pyio module which certainly can't use any custom C code.
 Does that mean that when I'm using x = _pyio.BufferedWriter(), I could loose
 data in the write buffer when the interpreter exits without me calling
 x.close(), but when using x = io.BufferedWriter(), the buffer is
 guaranteed to get flushed?

 I actually described the behavior of CPython 2 while not realizing
 that CPython 3 silently dropped this guarantee.  (I also never
 realized that Jython/IronPython don't have the same guarantee; they
 could, if they implement 'atexit', like we did in PyPy.  That's
 however more acceptable if the platform itself doesn't offer the
 guarantee.)

 Anyway, it's a guarantee that the C offers, so personally I find it
 reasonable to expect CPython files to offer it too; not offering it is
 kind of saying that there is a feature of C that is actually present
 at a higher level than the exact same feature in Python, which looks
 backward to me.

 Additionally, this might be introducing subtle bugs in programs when
 porting them to Python 3.

 However I realize that the two arguments presented above might not be
 accepted as relevant.  (http://bugs.python.org/issue17852)

Thanks for the research! I tried writing a test for this myself, but
failed to get the cyclic reference in place properly for it to happen.

Seems I'm not the only one who was unaware and/or surprised by he change
in behavior.


Best,

   -Nikolaus

-- 
 »Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C

___
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 instances

2013-04-29 Thread Marco Hemmelrath

First of all, hi, I'm new to this list.

Following the enum discussions on this list I am kind of confused about 
how enums and their respective instances, i.e. the values, should behave 
in normal context.
I apologize beforehand for the mass of questions because the following 
contains really many discussed things but they all kinda depend on one 
another, and for terminology which I might've missed.


Considering we have[1]:

class Color(enum):
red = 1
white = 2
other = undefined

class State(enum):
idle = 0
busy = 1
idling = idle
ideling = 0

together with the premises:

1. type(State.busy) == State
2. type(State) == enum
3. isinstance(State.idle, State)
4. State.idle is State.idle

which should mostly be agreed on (if I didn't misinterpret).


How would an enum instance (e.g. State.busy) behave in normal Python 
expressions? Should these instances just wrap their values and provide 
some simple overhead useful for enums?


I'll just note down a few examples of how I think it could work and 
express a few thoughts on them:


1. State.busy == 1
2. State.busy == Color.red
3. int(State.Busy) is 1
4. isinstance(State.busy, int)
5. Color.other.startswith(und)
6. State.busy is not 1
7. State.busy is not Color.red
8. State.idle in State
9. 0 in State # True, False or raise?
10. State.idling is State.idle
11. State.idle == State.idling
12. State.idle is not State.idling

1.  2.
Considering that enum components contain a value this value should be 
accessable and comperable. If it wasn't then there would be no real need 
to assign a value to it because everything must be compared using the is 
operator anyway. In this case an entirely new syntax could be 
implemented but since I think this is not what we want I'll skip this.


Futhermore, if enum instances should compare equal to their values but 
unequal to each other this creates weird circumstances like:

Color.red == 1 == State.busy -but- Color.red != State.busy == 1

3.
Similar to 1. an enum instance's value /should/ be accessable as an 
expression by itself when needed besides simple operations like 
compatisons. This might be really tricky because the object in question 
is still of type State and some existing uses might break even though I 
can't think of any.


What would certainly be a problem in this case though is that repr() 
would not reveal the value but the actual enum instance. This could be 
problematic when the enum instance's value is not a standard type or 
when repr() and str() differ and repr() is what's needed.


4.
Combines 1. and 2. in class relation. It could be argued that the actual 
value should be an instance of its type subclassed by the enum class 
(State) which is in turn a subclass of enum.


Going further on this it could also allow various things like class 
EnumWithInt(enum, int) which would only allow integers as its enum 
identifiers. This goes slightly into the IntEnum direction but with more 
flexibility.


5.
Related to 3. in that this also allows attribute access to the enum 
instance's value. Considering that the enum instance should already be 
an instance of its value type as well this kinda speaks for itself.


6.  7.
Obviously, these can't be true even though they compare equal (see 1. 
and 2.).


8.
Check if an enum instance is a member of State. Since in this case the 
same can also be achieved by using isinstance or by comparing the 
instance's type, this is mostly interesting for subclassing enums 
because, but I won't that cover here because it would probably be too much.


9.
Analog to 8. this could either return just work, simply return False 
because this object is obviously not a member of State or raise an 
exception because of a type mismatch (not an enum instance). Also 
interesting for subclassing enums.


10.
See premise 4. on this.

11.  12.
Even though these compare equal and even if their value object is 
actually the same they themseves should /not/ be the same object. 
Someone needs to find a use case for this though because as of now I can 
only think of this being Pythonic.




So, the most critical part of this would probably be 3. to 7. regarding 
the value types. I'd love to read some thoughts and comments on that.



Regards,
Marco

[1]: http://mail.python.org/pipermail/python-dev/2013-April/125738.html
___
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] Enumeration item arguments?

2013-04-29 Thread Philip Jenvey

On Apr 29, 2013, at 3:25 PM, Eli Bendersky wrote:

 On Mon, Apr 29, 2013 at 2:59 PM, Ethan Furman et...@stoneleaf.us wrote:
 In the Planet example we saw the possibility of specifying arguments to enum 
 item __init__:
 
 class Planet(Enum):
 MERCURY = (3.303e+23, 2.4397e6)
 VENUS   = (4.869e+24, 6.0518e6)
 EARTH   = (5.976e+24, 6.37814e6)
 MARS= (6.421e+23, 3.3972e6)
 JUPITER = (1.9e+27,   7.1492e7)
 SATURN  = (5.688e+26, 6.0268e7)
 URANUS  = (8.686e+25, 2.5559e7)
 NEPTUNE = (1.024e+26, 2.4746e7)
 
 def __init__(self, mass, radius):
 self.mass = mass   # in kilograms
 self.radius = radius   # in meters
 
 Do we want to support this?
 
 I'm -1, and this is yet another bad sign of conflating enums with classes. If 
 planets want to have attributes and behaviors, let them be normal classes. If 
 they want a PlanetId *enum member*, that's OK, but there's no need to 
 intermix the two.

You may be right about the Planet example, but I wouldn't go that far. 
Additional metadata on Enum instances can be a handy feature in some cases, 
like documentation, e.g.:

class Protocol(Enum):

 HOPOPT = 0, IPv6 Hop-by-Hop Option
 ICMP = 1, Internet Control Message
 IGMP = 2, Internet Group Management

 @property
 def value(self):
 return self._value[0]

 @property
 def description(self):
   return self._value[1]


--
Philip Jenvey

___
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 instances

2013-04-29 Thread Ethan Furman

On 04/29/2013 06:23 PM, Marco Hemmelrath wrote:

First of all, hi, I'm new to this list.

Following the enum discussions on this list I am kind of confused about how 
enums and their respective instances, i.e.
the values, should behave in normal context.
I apologize beforehand for the mass of questions because the following 
contains really many discussed things but they
all kinda depend on one another, and for terminology which I might've missed.

Considering we have[1]:

 class Color(enum):
 red = 1
 white = 2
 other = undefined

 class State(enum):
 idle = 0
 busy = 1
 idling = idle
 ideling = 0

together with the premises:

 1. type(State.busy) == State
 2. type(State) == enum
 3. isinstance(State.idle, State)
 4. State.idle is State.idle

which should mostly be agreed on (if I didn't misinterpret).


How would an enum instance (e.g. State.busy) behave in normal Python 
expressions? Should these instances just wrap their
values and provide some simple overhead useful for enums?

I'll just note down a few examples of how I think it could work and express a 
few thoughts on them:

 1. State.busy == 1
 2. State.busy == Color.red
 3. int(State.Busy) is 1
 4. isinstance(State.busy, int)
 5. Color.other.startswith(und)
 6. State.busy is not 1
 7. State.busy is not Color.red
 8. State.idle in State
 9. 0 in State # True, False or raise?
 10. State.idling is State.idle
 11. State.idle == State.idling
 12. State.idle is not State.idling


1  2 are False (would be true if using `.value`)

3 is True

4  5 are False (again, need `.value`)

6 is not the correct way to use `is` (should be `==`)

7, 8, 9, 10, 11 are True

12 is False

___
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 instances

2013-04-29 Thread Nikolaus Rath
Marco Hemmelrath marco.hemmelr...@googlemail.com writes:
 class State(enum):
 idle = 0
 busy = 1
 idling = idle
 ideling = 0

 together with the premises:

 1. type(State.busy) == State
 2. type(State) == enum

State is a class, it just inherits from enum. Thus:

type(State) == type(enum) == type(EnumMetaclass)
issubclass(State, enum) == True


HTH,

   -Nikolaus

-- 
 »Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C

___
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 instances

2013-04-29 Thread Larry Hastings

On 04/29/2013 07:42 PM, Nikolaus Rath wrote:

State is a class, it just inherits from enum. Thus:

type(State) == type(enum) == type(EnumMetaclass)
issubclass(State, enum) == True


HTH,

-Nikolaus


If you'd tried it, you'd have found that that isn't true.  enum has a 
metaclass, EnumMetaclass.  Thus type(enum) == EnumMetaClass.


That didn't help,


//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] Enumeration items: mixed types?

2013-04-29 Thread Barry Warsaw
On Apr 29, 2013, at 04:16 PM, Ethan Furman wrote:

I suppose the other option is to have `.value` be whatever was assigned (1,
'really big country', and (8273.199, 517) ), and the fact that
`int(Stuff.china) ` blows up and doesn't store easily in a database is the
programmers issue...

Correct.  flufl.enum.IntEnums will blow up earlier, when the class is defined
assigning the attributes to non-int values.

-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] Enumeration item arguments?

2013-04-29 Thread Barry Warsaw
On Apr 29, 2013, at 03:25 PM, Eli Bendersky wrote:

I'm -1, and this is yet another bad sign of conflating enums with classes.
If planets want to have attributes and behaviors, let them be normal
classes. If they want a PlanetId *enum member*, that's OK, but there's no
need to intermix the two.

I agree with this.

-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] Enumeration item arguments?

2013-04-29 Thread Eli Bendersky
On Mon, Apr 29, 2013 at 7:30 PM, Philip Jenvey pjen...@underboss.orgwrote:


 On Apr 29, 2013, at 3:25 PM, Eli Bendersky wrote:

  On Mon, Apr 29, 2013 at 2:59 PM, Ethan Furman et...@stoneleaf.us
 wrote:
  In the Planet example we saw the possibility of specifying arguments to
 enum item __init__:
 
  class Planet(Enum):
  MERCURY = (3.303e+23, 2.4397e6)
  VENUS   = (4.869e+24, 6.0518e6)
  EARTH   = (5.976e+24, 6.37814e6)
  MARS= (6.421e+23, 3.3972e6)
  JUPITER = (1.9e+27,   7.1492e7)
  SATURN  = (5.688e+26, 6.0268e7)
  URANUS  = (8.686e+25, 2.5559e7)
  NEPTUNE = (1.024e+26, 2.4746e7)
 
  def __init__(self, mass, radius):
  self.mass = mass   # in kilograms
  self.radius = radius   # in meters
 
  Do we want to support this?
 
  I'm -1, and this is yet another bad sign of conflating enums with
 classes. If planets want to have attributes and behaviors, let them be
 normal classes. If they want a PlanetId *enum member*, that's OK, but
 there's no need to intermix the two.

 You may be right about the Planet example, but I wouldn't go that far.
 Additional metadata on Enum instances can be a handy feature in some cases,
 like documentation, e.g.:

 class Protocol(Enum):

  HOPOPT = 0, IPv6 Hop-by-Hop Option
  ICMP = 1, Internet Control Message
  IGMP = 2, Internet Group Management

  @property
  def value(self):
  return self._value[0]

  @property
  def description(self):
return self._value[1]


Note that I don't object to adding certain behaviors to enums. I'm against
taking it too far. One example of taking it too far is special
implementation provisions to make enum be more like other classes,
complicating the implementation just for this cause.

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