Re: [Python-Dev] PEP 4XX: pyzaa "Improving Python ZIP Application Support"
Steven D'Aprano writes: > > Give us a non-MS example, please. > I'm afraid I don't understand your question. There were two problems mentioned. Paul worries about 4-letter extensions under PowerShell. You mentioned conflicts in Linux file managers. In both cases, a bug on Windows in detecting Microsoft products would kill (or at least seriously maim) a shell or file manager. I doubt many have ever existed, and surely they were detected *and* corrected pretty much immediately. My point is that such bug-awareness would not extend as strongly to extensions used by third-party free software. > Are you suggesting that four letter extensions are restricted to > Microsoft products? No, of course not. > Common 4+ letter extensions include .html, .tiff, .jpeg, .mpeg, > .midi, .java and .torrent. All of which (except perhaps .java and .torrent, which I bet are most commonly invoked not from shells but from IDEs and webbrowsers which have their own internal association databases) are commonly abbreviated to three letters on Windows, including in HTTP URLs which should have no such issues at all. That is consistent with my point (and Paul's, I believe). It doesn't prove anything, but given the decreasing importance of extensions for file typing on all systems, I think there's little penalty to being shortsighted and following the 3-character convention for extensions, especially on Windows. ___ 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] PEP 4XX: pyzaa "Improving Python ZIP Application Support"
On 4 May 2013 07:48, Nick Coghlan wrote: > We don't need examples of arbitrary data file extentions, we need > examples of 4 letter extensions that are known to work correctly when > placed on PATHEXT, including when called from PowerShell. In the > absence of confirmation that 4-letter extensions work reliably in such > cases, it seems wise to abbreviate the Windows GUI application > extension as .pzw. > > I've also cc'ed Steve Dower, since investigation of this kind of > Windows behavioural question is one of the things he offered > distuils-sig help with after PyCon US :) Nick, thanks for passing this on. Your explanation of the issue is precisely correct. For information (I should have included this in the original message) here's the Powershell bug report I found: https://connect.microsoft.com/PowerShell/feedback/details/238550/power-shell-trimming-extension-to-3-characters-when-resolving-file-associations Unfortunately the link to the referenced discussion in that report is inaccessible :-( Paul ___ 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?
On 4 May 2013 07:42, "Nick Coghlan" wrote: > 2. We restore __getitem__ on EnumMetaclass *solely* for member lookup > by name (the "getmember" functionality above). This would leave > __call__ used for the reverse lookup (value to member and hence name) > and __getitem__ for the forward lookup (name to member and hence > value) (Note: given Ethan's comments about his current implementation, > I believe this actually fits nicely with the way > EnumMetaclass.__getattr__ is already implemented) This has the advantage of leaving one obvious way to do the 'reverse' lookup (namely __call__), rather than two redundant alternatives. Cheers, Phil ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Difference in RE between 3.2 and 3.3 (or Aaron Swartz memorial)
Hi Matej, On Thu, Mar 7, 2013 at 11:08 AM, Matej Cepl wrote: > if c is not ' ' and c is not ' ': > if c != ' ' and c != ' ': Sorry for the delay in answering, but I just noticed what is wrong in this "fix": it compares c with the same single-character ' ' twice, whereas the original compared it with ' ' and with the two-character ' '. 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] PEP 4XX: pyzaa "Improving Python ZIP Application Support"
On Sat, 04 May 2013 11:41:27 +1000 Steven D'Aprano wrote: > > > Rather than risk obscure bugs, I would suggest restricting the extensions > > to 3 characters. For the “Windowed Python ZIP Applications” case, could we > > use .pzw as the extension instead of .pyzw? > > I've had Linux systems which associated OpenOffice docs with Archive Manager > rather than OpenOffice. It's likely that at least some Linux systems will > likewise decide that .pyz files are archives, not Python files, and open them > in Archive Manager. What would that have to do with the file extension? If some Linux systems decide that .ods and .pyz files are archives, it's probably because they *are* archives in their own right (though specialized ones). Probably the libmagic (used e.g. by the `file` command) wasn't up-to-date enough to specifically recognize OpenOffice documents, so it simply recognized the ZIP file structure and detected the file as such. 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?
On Sat, 4 May 2013 16:42:08 +1000 Nick Coghlan wrote: > On Sat, May 4, 2013 at 4:10 PM, Georg Brandl wrote: > > Am 04.05.2013 01:22, schrieb Antoine Pitrou: > >> On Sat, 04 May 2013 11:15:17 +1200 > >> Greg Ewing wrote: > >>> Eli Bendersky wrote: > >>> > I'm just curious what it is about enums that sets everyone on a "let's > >>> > make things safer" path. Python is about duck typing, it's absolutely > >>> > "unsafe" in the static typing sense, in the most fundamental ways > >>> > imaginable. > >>> > >>> This isn't about catching bugs in the program, it's > >>> about validating user input. That's a common enough > >>> task that it deserves to have a convenient way to > >>> do it correctly. > >> > >> +1. An enum is basically a bidirectional mapping between some raw > >> values and some "nice" instances, so it deserves a well-defined lookup > >> operation in each direction. > > As I see it, there are 3 possible ways forward here: 4. Offer classmethods named Enum.by_name() and Enum.by_value(). Simple and explicit. Regards Antoine. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] enum discussion: can someone please summarize open issues?
On 05/04/2013 04:33 AM, Antoine Pitrou wrote: On Sat, 4 May 2013 16:42:08 +1000 Nick Coghlan wrote: On Sat, May 4, 2013 at 4:10 PM, Georg Brandl wrote: Am 04.05.2013 01:22, schrieb Antoine Pitrou: On Sat, 04 May 2013 11:15:17 +1200 Greg Ewing wrote: Eli Bendersky wrote: I'm just curious what it is about enums that sets everyone on a "let's make things safer" path. Python is about duck typing, it's absolutely "unsafe" in the static typing sense, in the most fundamental ways imaginable. This isn't about catching bugs in the program, it's about validating user input. That's a common enough task that it deserves to have a convenient way to do it correctly. +1. An enum is basically a bidirectional mapping between some raw values and some "nice" instances, so it deserves a well-defined lookup operation in each direction. As I see it, there are 3 possible ways forward here: 4. Offer classmethods named Enum.by_name() and Enum.by_value(). Simple and explicit. And then you can't have enum items named by_name and by_value. -- ~Ethan~ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] enum discussion: can someone please summarize open issues?
On 5/4/2013 2:42 AM, Nick Coghlan wrote: > On Sat, May 4, 2013 at 4:10 PM, Georg Brandl wrote: >> Am 04.05.2013 01:22, schrieb Antoine Pitrou: >>> On Sat, 04 May 2013 11:15:17 +1200 >>> Greg Ewing wrote: Eli Bendersky wrote: > I'm just curious what it is about enums that sets everyone on a "let's > make things safer" path. Python is about duck typing, it's absolutely > "unsafe" in the static typing sense, in the most fundamental ways > imaginable. This isn't about catching bugs in the program, it's about validating user input. That's a common enough task that it deserves to have a convenient way to do it correctly. >>> >>> +1. An enum is basically a bidirectional mapping between some raw >>> values and some "nice" instances, so it deserves a well-defined lookup >>> operation in each direction. > > As I see it, there are 3 possible ways forward here: > > 1. The current PEP, offering only "getattr(MyEnum, name)". > > If code needs to ensure non-enum values are detected immediately (such > as during translation of user input entered at a command prompt), then > they can either create a separate mapping using: > > lookup = {m.name, m for m in (getattr(MyEnum, name) for name in > dir(MyEnum)) if isinstance(m, MyEnum)} > > or else create a lookup function: > > def getmember(enum, name): > m = getattr(enum, name, None) > if not isinstance(m, enum): > raise KeyError("{!r} is not a member of {!r}".format(name, enum)) > return m > > 2. We restore __getitem__ on EnumMetaclass *solely* for member lookup > by name (the "getmember" functionality above). This would leave > __call__ used for the reverse lookup (value to member and hence name) > and __getitem__ for the forward lookup (name to member and hence > value) (Note: given Ethan's comments about his current implementation, > I believe this actually fits nicely with the way > EnumMetaclass.__getattr__ is already implemented) > > 3. We offer my earlier suggestion of an "as_dict()" method on the > metaclass, which implements the mapping calculation above. As others > pointed out, this has the same name clash problem as offering > additional non-special methods on namedtuple objects. > > I'm now -1 on my own as_dict() suggestion, due to the general name > clash problem for arbitrary enums. To avoid the name collision, namedtuple calls this _asdict(). -- Eric. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 379 Python launcher for Windows - behaviour for #!/usr/bin/env python line is wrong
Paul Moore gmail.com> writes: > This will mean that scripts written with #!/usr/bin/env python will > behave the same on Unix and Windows in the presence of activated > virtualenvs. Overall I think it's the right result. There's one other compatibility clarification: at the moment, as allowed by the PEP, you can have launcher flags in a line that starts with #!/usr/bin/env python, for example #!/usr/bin/env python3.2-32 -u In such a case the launcher would use the 3.2-32 suffix to indicate that 32-bit Python 3.2 is wanted, and pass the -u to the launched executable. I assume that this behaviour should continue, and the Posix-compatible behaviour being proposed should only apply for lines that contain "#!/usr/bin/env python" followed by whitespace. Also, since we're making a backwards incompatible change, do people feel that it needs to be switched on only in the presence of e.g. an environment variable such as PYLAUNCH_SEARCHPATH, or should we just change the default behaviour now and risk breaking user scripts which may rely on the current behaviour? Regards, Vinay Sajip ___ 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?
On Sat, 04 May 2013 06:37:23 -0700 Ethan Furman wrote: > > +1. An enum is basically a bidirectional mapping between some raw > values and some "nice" instances, so it deserves a well-defined lookup > operation in each direction. > >> > >> As I see it, there are 3 possible ways forward here: > > > > 4. Offer classmethods named Enum.by_name() and Enum.by_value(). > > Simple and explicit. > > And then you can't have enum items named by_name and by_value. You can. Normal shadowing rules apply. By the same token, you can't have enum items named __str__ or __init__. How is that a problem? Attribute resolution rules imply some restrictions, which are well-known to all Python programmers. But, really, you can decide on another name if you like: __byname__ or _byname, etc. My point is simply that lookup doesn't *have* to invoke operators, and explicitly named classmethods are less confusing than repurposed operators. Regards Antoine. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] enum discussion: can someone please summarize open issues?
Just to stop the bikeshedding, let's do #2. Put back __getitem__ solely for lookup by name. Keep __call__ (really __new__) for lookup by value or "pass-through" for members. --Guido On Fri, May 3, 2013 at 11:42 PM, Nick Coghlan wrote: > On Sat, May 4, 2013 at 4:10 PM, Georg Brandl wrote: >> Am 04.05.2013 01:22, schrieb Antoine Pitrou: >>> On Sat, 04 May 2013 11:15:17 +1200 >>> Greg Ewing wrote: Eli Bendersky wrote: > I'm just curious what it is about enums that sets everyone on a "let's > make things safer" path. Python is about duck typing, it's absolutely > "unsafe" in the static typing sense, in the most fundamental ways > imaginable. This isn't about catching bugs in the program, it's about validating user input. That's a common enough task that it deserves to have a convenient way to do it correctly. >>> >>> +1. An enum is basically a bidirectional mapping between some raw >>> values and some "nice" instances, so it deserves a well-defined lookup >>> operation in each direction. > > As I see it, there are 3 possible ways forward here: > > 1. The current PEP, offering only "getattr(MyEnum, name)". > > If code needs to ensure non-enum values are detected immediately (such > as during translation of user input entered at a command prompt), then > they can either create a separate mapping using: > > lookup = {m.name, m for m in (getattr(MyEnum, name) for name in > dir(MyEnum)) if isinstance(m, MyEnum)} > > or else create a lookup function: > > def getmember(enum, name): > m = getattr(enum, name, None) > if not isinstance(m, enum): > raise KeyError("{!r} is not a member of {!r}".format(name, enum)) > return m > > 2. We restore __getitem__ on EnumMetaclass *solely* for member lookup > by name (the "getmember" functionality above). This would leave > __call__ used for the reverse lookup (value to member and hence name) > and __getitem__ for the forward lookup (name to member and hence > value) (Note: given Ethan's comments about his current implementation, > I believe this actually fits nicely with the way > EnumMetaclass.__getattr__ is already implemented) > > 3. We offer my earlier suggestion of an "as_dict()" method on the > metaclass, which implements the mapping calculation above. As others > pointed out, this has the same name clash problem as offering > additional non-special methods on namedtuple objects. > > I'm now -1 on my own as_dict() suggestion, due to the general name > clash problem for arbitrary enums. > > Options 1 and 2 both sound reasonable to me, although I have a > preference for 2 due to the ability to produce a more appropriate > error message when the lookup fails. > > Cheers, > Nick. > > -- > Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia > ___ > Python-Dev mailing list > Python-Dev@python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > http://mail.python.org/mailman/options/python-dev/guido%40python.org -- --Guido van Rossum (python.org/~guido) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 379 Python launcher for Windows - behaviour for #!/usr/bin/env python line is wrong
On 4 May 2013 15:20, Vinay Sajip wrote: > Paul Moore gmail.com> writes: > > > This will mean that scripts written with #!/usr/bin/env python will > > behave the same on Unix and Windows in the presence of activated > > virtualenvs. > > Overall I think it's the right result. There's one other compatibility > clarification: at the moment, as allowed by the PEP, you can have launcher > flags in a line that starts with #!/usr/bin/env python, for example > > #!/usr/bin/env python3.2-32 -u > > In such a case the launcher would use the 3.2-32 suffix to indicate that > 32-bit Python 3.2 is wanted, and pass the -u to the launched executable. I > assume that this behaviour should continue, and the Posix-compatible > behaviour > being proposed should only apply for lines that contain > > "#!/usr/bin/env python" > > followed by whitespace. > That sounds reasonable - I've never used the ability to add flags, but I agree that as there's no equivalent in POSIX, there's no reason to change the current behaviour in that case. > Also, since we're making a backwards incompatible change, do people feel > that > it needs to be switched on only in the presence of e.g. an environment > variable > such as PYLAUNCH_SEARCHPATH, or should we just change the default behaviour > now and risk breaking user scripts which may rely on the current behaviour? > Personally, I'd say make it unconditional - the current behaviour is unlikely to ever be what people actually *want*. But if the consensus is to make it conditional, could we have a flag in py.ini rather than an environment variable? That would be more consistent with normal Windows practice. Paul. PS Vinay - from this post, I assume you're already looking at this code? I was considering trying to put together a patch, but I don't want to duplicate effort if you're working on it. ___ 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] PEP 379 Python launcher for Windows - behaviour for #!/usr/bin/env python line is wrong
Paul Moore gmail.com> writes: > PS Vinay - from this post, I assume you're already looking at this > code? I was considering trying to put together a patch, but I don't want to > duplicate effort if you're working on it. I've taken a quick look at it, but I probably won't be able to make any changes until the near the end of the coming week. Feel free to have a go; the place to make changes will be near the call is_virt = parse_shebang(...) ... if (!is_virt) { ... } else { /* In here is where the new logic will probably go. */ } Also, the #define SEARCH_PATH needs to be uncommented to include the find_on_path function. It also enables searching the path for customised commands. Regards, Vinay ___ 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] [Python-checkins] cpython: #17115, 17116: Have modules initialize the __package__ and __loader__
FYI, I'm aware this broke some buildbots and will have a look today to figure out why. On Sat, May 4, 2013 at 1:57 PM, brett.cannon wrote: > http://hg.python.org/cpython/rev/e39a8f8ceb9f > changeset: 83607:e39a8f8ceb9f > user:Brett Cannon > date:Sat May 04 13:56:58 2013 -0400 > summary: > #17115,17116: Have modules initialize the __package__ and __loader__ > attributes to None. > > The long-term goal is for people to be able to rely on these > attributes existing and checking for None to see if they have been > set. Since import itself sets these attributes when a loader does not > the only instances when the attributes are None are from someone > overloading __import__() and not using a loader or someone creating a > module from scratch. > > This patch also unifies module initialization. Before you could have > different attributes with default values depending on how the module > object was created. Now the only way to not get the same default set > of attributes is to circumvent initialization by calling > ModuleType.__new__() directly. > > files: > Doc/c-api/module.rst| 11 +- > Doc/library/importlib.rst |2 +- > Doc/reference/import.rst|4 +- > Doc/whatsnew/3.4.rst|5 + > Lib/ctypes/test/__init__.py |2 +- > Lib/doctest.py |2 +- > Lib/importlib/_bootstrap.py |2 +- > Lib/inspect.py |2 +- > Lib/test/test_descr.py |4 +- > Lib/test/test_importlib/test_api.py | 14 +- > Lib/test/test_module.py | 28 +- > Misc/NEWS |3 + > Objects/moduleobject.c | 39 +- > Python/importlib.h | 363 --- > Python/pythonrun.c |3 +- > 15 files changed, 264 insertions(+), 220 deletions(-) > > > diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst > --- a/Doc/c-api/module.rst > +++ b/Doc/c-api/module.rst > @@ -35,13 +35,20 @@ >single: __name__ (module attribute) >single: __doc__ (module attribute) >single: __file__ (module attribute) > + single: __package__ (module attribute) > + single: __loader__ (module attribute) > > Return a new module object with the :attr:`__name__` attribute set to > *name*. > - Only the module's :attr:`__doc__` and :attr:`__name__` attributes are > filled in; > - the caller is responsible for providing a :attr:`__file__` attribute. > + The module's :attr:`__name__`, :attr:`__doc__`, :attr:`__package__`, and > + :attr:`__loader__` attributes are filled in (all but :attr:`__name__` are > set > + to ``None``); the caller is responsible for providing a :attr:`__file__` > + attribute. > > .. versionadded:: 3.3 > > + .. versionchanged:: 3.4 > + :attr:`__package__` and :attr:`__loader__` are set to ``None``. > + > > .. c:function:: PyObject* PyModule_New(const char *name) > > diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst > --- a/Doc/library/importlib.rst > +++ b/Doc/library/importlib.rst > @@ -827,7 +827,7 @@ >decorator as it subsumes this functionality. > > .. versionchanged:: 3.4 > - Set ``__loader__`` if set to ``None`` as well if the attribute does not > + Set ``__loader__`` if set to ``None``, as if the attribute does not >exist. > > > diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst > --- a/Doc/reference/import.rst > +++ b/Doc/reference/import.rst > @@ -423,8 +423,8 @@ > * If the module has a ``__file__`` attribute, this is used as part of the > module's repr. > > - * If the module has no ``__file__`` but does have a ``__loader__``, then the > - loader's repr is used as part of the module's repr. > + * If the module has no ``__file__`` but does have a ``__loader__`` that is > not > + ``None``, then the loader's repr is used as part of the module's repr. > > * Otherwise, just use the module's ``__name__`` in the repr. > > diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst > --- a/Doc/whatsnew/3.4.rst > +++ b/Doc/whatsnew/3.4.rst > @@ -231,3 +231,8 @@ >:exc:`NotImplementedError` blindly. This will only affect code calling >:func:`super` and falling through all the way to the ABCs. For > compatibility, >catch both :exc:`NotImplementedError` or the appropriate exception as > needed. > + > +* The module type now initializes the :attr:`__package__` and > :attr:`__loader__` > + attributes to ``None`` by default. To determine if these attributes were > set > + in a backwards-compatible fashion, use e.g. > + ``getattr(module, '__loader__', None) is not None``. > \ No newline at end of file > diff --git a/Lib/ctypes/test/__init__.py b/Lib/ctypes/test/__init__.py > --- a/Lib/ctypes/test/__init__.py > +++ b/Lib/ctypes/test/__init__.py > @@ -37,7 +37,7 @@ > > def find_package_modules(package, mask): > import fnmatch > -if (hasa
[Python-Dev] PEP 435 - requesting pronouncement
Hello pydev, PEP 435 is ready for final review. A lot of the feedback from the last few weeks of discussions has been incorporated. Naturally, not everything could go in because some minor (mostly preference-based) issues did not reach a consensus. We do feel, however, that the end result is better than in the beginning and that Python can finally have a useful enumeration type in the standard library. I'm attaching the latest version of the PEP for convenience. If you've read previous versions, the easiest way to get acquainted with the recent changes is to go through the revision log at http://hg.python.org/peps A reference implementation for PEP 435 is available at https://bitbucket.org/stoneleaf/ref435 Kind regards and happy weekend. PEP: 435 Title: Adding an Enum type to the Python standard library Version: $Revision$ Last-Modified: $Date$ Author: Barry Warsaw , Eli Bendersky , Ethan Furman Status: Draft Type: Standards Track Content-Type: text/x-rst Created: 2013-02-23 Python-Version: 3.4 Post-History: 2013-02-23, 2013-05-02 Abstract This PEP proposes adding an enumeration type to the Python standard library. An enumeration is a set of symbolic names bound to unique, constant values. Within an enumeration, the values can be compared by identity, and the enumeration itself can be iterated over. Decision TODO: update decision here once pronouncement is made. [1]_ Status of discussions = The idea of adding an enum type to Python is not new - PEP 354 [2]_ is a previous attempt that was rejected in 2005. Recently a new set of discussions was initiated [3]_ on the ``python-ideas`` mailing list. Many new ideas were proposed in several threads; after a lengthy discussion Guido proposed adding ``flufl.enum`` to the standard library [4]_. During the PyCon 2013 language summit the issue was discussed further. It became clear that many developers want to see an enum that subclasses ``int``, which can allow us to replace many integer constants in the standard library by enums with friendly string representations, without ceding backwards compatibility. An additional discussion among several interested core developers led to the proposal of having ``IntEnum`` as a special case of ``Enum``. The key dividing issue between ``Enum`` and ``IntEnum`` is whether comparing to integers is semantically meaningful. For most uses of enumerations, it's a **feature** to reject comparison to integers; enums that compare to integers lead, through transitivity, to comparisons between enums of unrelated types, which isn't desirable in most cases. For some uses, however, greater interoperatiliby with integers is desired. For instance, this is the case for replacing existing standard library constants (such as ``socket.AF_INET``) with enumerations. Further discussion in late April 2013 led to the conclusion that enumeration members should belong to the type of their enum: ``type(Color.red) == Color``. Guido has pronounced a decision on this issue [5]_, as well as related issues of not allowing to subclass enums [6]_, unless they define no enumeration members [7]_. Motivation == *[Based partly on the Motivation stated in PEP 354]* The properties of an enumeration are useful for defining an immutable, related set of constant values that have a defined sequence but no inherent semantic meaning. Classic examples are days of the week (Sunday through Saturday) and school assessment grades ('A' through 'D', and 'F'). Other examples include error status values and states within a defined process. It is possible to simply define a sequence of values of some other basic type, such as ``int`` or ``str``, to represent discrete arbitrary values. However, an enumeration ensures that such values are distinct from any others including, importantly, values within other enumerations, and that operations without meaning ("Wednesday times two") are not defined for these values. It also provides a convenient printable representation of enum values without requiring tedious repetition while defining them (i.e. no ``GREEN = 'green'``). Module and type name We propose to add a module named ``enum`` to the standard library. The main type exposed by this module is ``Enum``. Hence, to import the ``Enum`` type user code will run:: >>> from enum import Enum Proposed semantics for the new enumeration type === Creating an Enum Enumerations are created using the class syntax, which makes them easy to read and write. An alternative creation method is described in `Functional API`_. To define an enumeration, subclass ``Enum`` as follows:: >>> from enum import Enum >>> class Color(Enum): ... red = 1 ... green = 2 ... blue = 3 **A note on nomenclature**: we call ``Color`` an *enumeration* (or *enum*) and ``Color.red``, ``Color.green`` are *enumerat
Re: [Python-Dev] PEP 435 - requesting pronouncement
Great job guys. Victor Le 5 mai 2013 00:06, "Eli Bendersky" a écrit : > Hello pydev, > > PEP 435 is ready for final review. A lot of the feedback from the last few > weeks of discussions has been incorporated. Naturally, not everything could > go in because some minor (mostly preference-based) issues did not reach a > consensus. We do feel, however, that the end result is better than in the > beginning and that Python can finally have a useful enumeration type in the > standard library. > > I'm attaching the latest version of the PEP for convenience. If you've > read previous versions, the easiest way to get acquainted with the recent > changes is to go through the revision log at http://hg.python.org/peps > > A reference implementation for PEP 435 is available at > https://bitbucket.org/stoneleaf/ref435 > > Kind regards and happy weekend. > > > > > > ___ > 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/victor.stinner%40gmail.com > > ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] enum discussion: can someone please summarize open issues?
On 05/04/2013 07:01 AM, Eric V. Smith wrote: On 5/4/2013 2:42 AM, Nick Coghlan wrote: I'm now -1 on my own as_dict() suggestion, due to the general name clash problem for arbitrary enums. To avoid the name collision, namedtuple calls this _asdict(). Although I recall Raymond told me he should have called it asdict_(), and reserved all identifiers with trailing underscores. //arry/ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 435 - requesting pronouncement
Typo line 171: One thing I'd like to be clear in the PEP about is whether enum_type and _EnumDict._enum_names should be documented, or whether they're considered implementation details. I'd like to make a subclass of Enum that accepts ... for auto-valued enums but that requires subclassing the metaclass and access to classdict._enum_names. I can get to enum_type via type(Enum), but _EnumDict._enum_names requires knowing the attribute. It would sufficient for my purposes if it was just documented that the passed classdict had a _enum_names attribute. In testing the below, I've also discovered a bug in the reference implementation - currently it will not handle an __mro__ like: (, , , , ) Apply the following patch to make that work: diff -r 758d43b9f732 ref435.py --- a/ref435.py Fri May 03 18:59:32 2013 -0700 +++ b/ref435.py Sun May 05 09:23:25 2013 +1000 @@ -116,7 +116,11 @@ if bases[-1] is Enum: obj_type = bases[0] else: -obj_type = bases[-1].__mro__[1] # e.g. (IntEnum, int, Enum, object) +for base in bases[-1].__mro__: +if not issubclass(base, Enum): +obj_type = base +break + else: obj_type = object # save enum items into separate mapping so they don't get baked into My auto-enum implementation (using the above patch - without it you can get the essentially the same results with class AutoIntEnum(int, Enum, metaclass=auto_enum). class auto_enum(type(Enum)): def __new__(metacls, cls, bases, classdict): temp = type(classdict)() names = set(classdict._enum_names) i = 0 for k in classdict._enum_names: v = classdict[k] if v is Ellipsis: v = i else: i = v i += 1 temp[k] = v for k, v in classdict.items(): if k not in names: temp[k] = v return super(auto_enum, metacls).__new__(metacls, cls, bases, temp) class AutoNumberedEnum(Enum, metaclass=auto_enum): pass class AutoIntEnum(IntEnum, metaclass=auto_enum): pass class TestAutoNumber(AutoNumberedEnum): a = ... b = 3 c = ... class TestAutoInt(AutoIntEnum): a = ... b = 3 c = ... print(TestAutoNumber, list(TestAutoNumber)) print(TestAutoInt, list(TestAutoInt)) -- Run -- [, , ] [, , ] Tim Delaney ___ 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?
Hm. Trailing underscores look *really* weird to me. On Sat, May 4, 2013 at 3:41 PM, Larry Hastings wrote: > On 05/04/2013 07:01 AM, Eric V. Smith wrote: > > On 5/4/2013 2:42 AM, Nick Coghlan wrote: > > I'm now -1 on my own as_dict() suggestion, due to the general name > clash problem for arbitrary enums. > > To avoid the name collision, namedtuple calls this _asdict(). > > > Although I recall Raymond told me he should have called it asdict_(), and > reserved all identifiers with trailing underscores. > > > /arry > > ___ > Python-Dev mailing list > Python-Dev@python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > http://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (python.org/~guido) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 435 - requesting pronouncement
On Sat, May 4, 2013 at 4:27 PM, Tim Delaney wrote: > Typo line 171: > > Fixed, thanks. > One thing I'd like to be clear in the PEP about is whether enum_type and > _EnumDict._enum_names should be documented, or whether they're considered > implementation details. > > No, they should not. Not only are they implementation details, they are details of the *reference implementation*, not the actual stdlib module. The reference implementation will naturally serve as a basis for the stdlib module, but it still has to undergo a review in which implementation details can change. Note that usually we do not document implementation details of stdlib modules, but this doesn't prevent some people from using them if they really want to. > I'd like to make a subclass of Enum that accepts ... for auto-valued enums > but that requires subclassing the metaclass and access to > classdict._enum_names. I can get to enum_type via type(Enum), but > _EnumDict._enum_names requires knowing the attribute. It would sufficient > for my purposes if it was just documented that the passed classdict had a > _enum_names attribute. > > In testing the below, I've also discovered a bug in the reference > implementation - currently it will not handle an __mro__ like: > > Thanks! Tim - did you sign the contributor CLA for Python? Since the reference implementation is aimed for becoming the stdlib enum eventually, we'd probably need you to sign that before we can accept patches from you. Eli > (, , , , > ) > > Apply the following patch to make that work: > > diff -r 758d43b9f732 ref435.py > --- a/ref435.py Fri May 03 18:59:32 2013 -0700 > +++ b/ref435.py Sun May 05 09:23:25 2013 +1000 > @@ -116,7 +116,11 @@ > if bases[-1] is Enum: > obj_type = bases[0] > else: > -obj_type = bases[-1].__mro__[1] # e.g. (IntEnum, int, > Enum, object) > +for base in bases[-1].__mro__: > +if not issubclass(base, Enum): > +obj_type = base > +break > + > else: > obj_type = object > # save enum items into separate mapping so they don't get baked > into > > My auto-enum implementation (using the above patch - without it you can > get the essentially the same results with class AutoIntEnum(int, Enum, > metaclass=auto_enum). > > class auto_enum(type(Enum)): > def __new__(metacls, cls, bases, classdict): > temp = type(classdict)() > names = set(classdict._enum_names) > i = 0 > > for k in classdict._enum_names: > v = classdict[k] > > if v is Ellipsis: > v = i > else: > i = v > > i += 1 > temp[k] = v > > for k, v in classdict.items(): > if k not in names: > temp[k] = v > > return super(auto_enum, metacls).__new__(metacls, cls, bases, temp) > > class AutoNumberedEnum(Enum, metaclass=auto_enum): > pass > > class AutoIntEnum(IntEnum, metaclass=auto_enum): > pass > > class TestAutoNumber(AutoNumberedEnum): > a = ... > b = 3 > c = ... > > class TestAutoInt(AutoIntEnum): > a = ... > b = 3 > c = ... > > print(TestAutoNumber, list(TestAutoNumber)) > print(TestAutoInt, list(TestAutoInt)) > > -- Run -- > [, , > ] > [, , > ] > > Tim Delaney > ___ 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] PEP 435 - requesting pronouncement
On 5 May 2013 10:49, Eli Bendersky wrote: > > On Sat, May 4, 2013 at 4:27 PM, Tim Delaney > wrote: > >> Typo line 171: >> >> > Fixed, thanks. > > > >> One thing I'd like to be clear in the PEP about is whether enum_type and >> _EnumDict._enum_names should be documented, or whether they're considered >> implementation details. >> >> > No, they should not. Not only are they implementation details, they are > details of the *reference implementation*, not the actual stdlib module. > The reference implementation will naturally serve as a basis for the stdlib > module, but it still has to undergo a review in which implementation > details can change. Note that usually we do not document implementation > details of stdlib modules, but this doesn't prevent some people from using > them if they really want to. > I think it would be useful to have some guaranteed method for a sub-metaclass to get the list of enum keys before calling the base class __new__. Not being able to do so removes a large number of possible extensions (like auto-numbering). > In testing the below, I've also discovered a bug in the reference >> implementation - currently it will not handle an __mro__ like: >> > > Thanks! Tim - did you sign the contributor CLA for Python? Since the > reference implementation is aimed for becoming the stdlib enum eventually, > we'd probably need you to sign that before we can accept patches from you. > I have now (just waiting on the confirmation email). Haven't submitted a patch since the CLAs were started ... Tim Delaney ___ 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] CLA link from bugs.python.org
It appears there's no obvious link from bugs.python.org to the contributor agreement - you need to go via the unintuitive link Foundation -> Contribution Forms (and from what I've read, you're prompted when you add a patch to the tracker). I'd suggest that if the "Contributor Form Received" field is "No" in user details, there be a link to http://www.python.org/psf/contrib/. Tim Delaney ___ 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] PEP 435 - requesting pronouncement
On 5 May 2013 11:22, Tim Delaney wrote: > On 5 May 2013 10:49, Eli Bendersky wrote: > >> >> On Sat, May 4, 2013 at 4:27 PM, Tim Delaney >> wrote: >> >>> Typo line 171: >>> >>> >> Fixed, thanks. >> >> >> >>> One thing I'd like to be clear in the PEP about is whether enum_type and >>> _EnumDict._enum_names should be documented, or whether they're considered >>> implementation details. >>> >>> >> No, they should not. Not only are they implementation details, they are >> details of the *reference implementation*, not the actual stdlib module. >> The reference implementation will naturally serve as a basis for the stdlib >> module, but it still has to undergo a review in which implementation >> details can change. Note that usually we do not document implementation >> details of stdlib modules, but this doesn't prevent some people from using >> them if they really want to. >> > > I think it would be useful to have some guaranteed method for a > sub-metaclass to get the list of enum keys before calling the base class > __new__. Not being able to do so removes a large number of possible > extensions (like auto-numbering). > I've been able to achieve the auto-numbering without relying on the internal implementation at all (with a limitation), with a single change to enum_type.__new__. My previous patch was slightly wrong - fix below as well. All existing tests pass. BTW, for mix-ins it's required that they have __slots__ = () - might want to mention that in the PEP. diff -r 758d43b9f732 ref435.py --- a/ref435.py Fri May 03 18:59:32 2013 -0700 +++ b/ref435.py Sun May 05 13:10:11 2013 +1000 @@ -116,7 +116,17 @@ if bases[-1] is Enum: obj_type = bases[0] else: -obj_type = bases[-1].__mro__[1] # e.g. (IntEnum, int, Enum, object) +obj_type = None + +for base in bases: +for c in base.__mro__: +if not issubclass(c, Enum): +obj_type = c +break + +if obj_type is not None: +break + else: obj_type = object # save enum items into separate mapping so they don't get baked into @@ -142,6 +152,7 @@ if obj_type in (object, Enum): enum_item = object.__new__(enum_class) else: +value = obj_type.__new__(obj_type, value) enum_item = obj_type.__new__(enum_class, value) enum_item._value = value enum_item._name = e Implementation: class AutoInt(int): __slots__ = () # Required def __new__(cls, value): if value is Ellipsis: try: i = cls._auto_number except AttributeError: i = cls._auto_number = 0 else: i = cls._auto_number = value cls._auto_number += 1 return int.__new__(cls, i) class AutoIntEnum(AutoInt, IntEnum): pass class TestAutoIntEnum(AutoIntEnum): a = ... b = 3 c = ... print(TestAutoIntEnum, list(TestAutoIntEnum)) -- Run -- [, , ] The implementation is not quite as useful - there's no immediately-obvious way to have an auto-numbered enum that is not also an int enum e.g. if you define class AutoNumberedEnum(AutoInt, Enum) it's still an int subclass. Tim Delaney ___ 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] PEP 435 - requesting pronouncement
On 5 May 2013 13:11, Tim Delaney wrote: > @@ -142,6 +152,7 @@ > if obj_type in (object, Enum): > enum_item = object.__new__(enum_class) > else: > +value = obj_type.__new__(obj_type, value) > enum_item = obj_type.__new__(enum_class, value) > enum_item._value = value > enum_item._name = e > Bugger - this is wrong (it didn't feel right to me) - I'm sure it's only working for me by accident. Need to think of something better. Tim Delaney ___ 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] PEP 435 - requesting pronouncement
On 05/04/2013 08:11 PM, Tim Delaney wrote: I've been able to achieve the auto-numbering without relying on the internal implementation at all (with a limitation), with a single change to enum_type.__new__. My previous patch was slightly wrong - fix below as well. All existing tests pass. BTW, for mix-ins it's required that they have __slots__ = () - might want to mention that in the PEP. What happens without `__slots__ = ()` ? -- ~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] PEP 435 - requesting pronouncement
On 5 May 2013 13:32, Ethan Furman wrote: > On 05/04/2013 08:11 PM, Tim Delaney wrote: > >> >> I've been able to achieve the auto-numbering without relying on the >> internal implementation at all (with a >> limitation), with a single change to enum_type.__new__. My previous patch >> was slightly wrong - fix below as well. All >> existing tests pass. BTW, for mix-ins it's required that they have >> __slots__ = () - might want to mention that in the PEP. >> > > What happens without `__slots__ = ()` ? > Traceback (most recent call last): File "D:\Development\ref435\ref435.py", line 311, in class AutoIntEnum(AutoInt, IntEnum): File "D:\Development\ref435\ref435.py", line 138, in __new__ enum_class = type.__new__(metacls, cls, bases, classdict) TypeError: multiple bases have instance lay-out conflict Tim Delaney ___ 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] PEP 435 - requesting pronouncement
On Sat, May 4, 2013 at 8:22 PM, Tim Delaney wrote: > On 5 May 2013 13:11, Tim Delaney wrote: > >> @@ -142,6 +152,7 @@ >> if obj_type in (object, Enum): >> enum_item = object.__new__(enum_class) >> else: >> +value = obj_type.__new__(obj_type, value) >> enum_item = obj_type.__new__(enum_class, value) >> enum_item._value = value >> enum_item._name = e >> > > Bugger - this is wrong (it didn't feel right to me) - I'm sure it's only > working for me by accident. Need to think of something better. > > Tim Delaney > > Could you please split this off to a separate thread? I'd like to keep this one for raising issues with the actual contents of the PEP and discussing whether this version is good enough for pronouncement. Thanks, Eli ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] PEP 435 - reference implementation discussion
Split off from the PEP 435 - requesting pronouncement thread. Think I've come up with a system that works for my auto-numbering case without knowing the internals of enum_type. Patch passes all existing test cases. The patch does two things: 1. Finds the first non-Enum class on the MRO of the new class and uses that as the enum type. 2. Instead of directly setting the _name and _value of the enum_item, it lets the Enum class do it via Enum.__init__(). Subclasses can override this. This gives Enums a 2-phase construction just like other classes. diff -r 758d43b9f732 ref435.py --- a/ref435.py Fri May 03 18:59:32 2013 -0700 +++ b/ref435.py Sun May 05 13:43:56 2013 +1000 @@ -116,7 +116,17 @@ if bases[-1] is Enum: obj_type = bases[0] else: -obj_type = bases[-1].__mro__[1] # e.g. (IntEnum, int, Enum, object) +obj_type = None + +for base in bases: +for c in base.__mro__: +if not issubclass(c, Enum): +obj_type = c +break + +if obj_type is not None: +break + else: obj_type = object # save enum items into separate mapping so they don't get baked into @@ -143,8 +153,7 @@ enum_item = object.__new__(enum_class) else: enum_item = obj_type.__new__(enum_class, value) -enum_item._value = value -enum_item._name = e +enum_item.__init__(e, value) enum_map[e] = enum_item enum_class.__aliases__ = aliases # non-unique enums names enum_class._enum_names = enum_names # enum names in definition order @@ -232,6 +241,10 @@ return enum raise ValueError("%s is not a valid %s" % (value, cls.__name__)) +def __init__(self, name, value): +self._name = name +self._value = value + def __repr__(self): return "<%s.%s: %r>" % (self.__class__.__name__, self._name, self._value) Auto-int implementation: class AutoInt(int): __slots__ = () def __new__(cls, value): if value is Ellipsis: try: i = cls._auto_number except AttributeError: i = cls._auto_number = 0 else: i = cls._auto_number = value cls._auto_number += 1 return int.__new__(cls, i) class AutoIntEnum(AutoInt, IntEnum): def __init__(self, name, value): super(AutoIntEnum, self).__init__(name, int(self)) class TestAutoIntEnum(AutoIntEnum): a = ... b = 3 c = ... class TestAutoIntEnum2(AutoIntEnum): a = ... b = ... c = ... print(TestAutoIntEnum, list(TestAutoIntEnum)) print(TestAutoIntEnum2, list(TestAutoIntEnum2)) -- Run -- [, , ] [, , ] Tim Delaney ___ 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] CLA link from bugs.python.org
Hi, On Sun, May 5, 2013 at 4:23 AM, Tim Delaney wrote: > It appears there's no obvious link from bugs.python.org to the contributor > agreement - you need to go via the unintuitive link Foundation -> > Contribution Forms (and from what I've read, you're prompted when you add a > patch to the tracker). > > I'd suggest that if the "Contributor Form Received" field is "No" in user > details, there be a link to http://www.python.org/psf/contrib/. > See http://psf.upfronthosting.co.za/roundup/meta/issue461. Best Regards, Ezio Melotti > Tim Delaney > ___ 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] PEP 435 - reference implementation discussion
On 05/04/2013 10:59 PM, Ethan Furman wrote: On 05/04/2013 08:50 PM, Tim Delaney wrote: Think I've come up with a system that works for my auto-numbering case without knowing the internals of enum_type. Patch passes all existing test cases. The patch does two things: [snip] 2. Instead of directly setting the _name and _value of the enum_item, it lets the Enum class do it via Enum.__init__(). Subclasses can override this. This gives Enums a 2-phase construction just like other classes. Not sure I care for this. Enums are, at least in theory, immutable objects, and immutable objects don't call __init__. Okay, still thinking about `value`, but as far as `name` goes, it should not be passed -- it must be the same as it was in the class definition or we could end up with something like: --> class AreYouKiddingMe(WierdEnum): ... who = 1 ... what = 2 ... when = 3 ... where = 4 ... why = 5 --> list(AreYouKiddingMe) [ , , , , , ] and that's assuming we made more changes to support such insane behavior; otherwise it would just break. So no passing of `name`, it gets set in the metaclass. -- ~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] PEP 435 - ref impl disc 2
So I have a class based on Nick's Named Values, that has been extended to propagate names into expressions, so that if you have named values 'x' and 'y', when you x + y, the result is a named value whose name is '(x + y)'. Seems pretty awkward to integrate this with Enum. Maybe I'm missing something. Here's carved down code with just one operator defined for brevity. The third item from each print statement should be the same, as far as I understand... but isn't. class NamedInt( int ): _count = 0 def __new__( cls, *args, **kwds ): name, *args = args if len( args ) == 0: args = [ cls._count ] cls._count += 1 self = super().__new__( cls, *args, **kwds ) self._name = name return self def __init__( self, *args, **kwds ): name, *args = args super().__init__() @property def __name__( self ): return self._name def __repr__( self ): # repr() is updated to include the name and type info return "{}({!r}, {})".format(type(self).__name__, self.__name__, super().__repr__()) def __str__( self ): # str() is unchanged, even if it relies on the repr() fallback base = super() base_str = base.__str__ if base_str.__objclass__ is object: return base.__repr__() return base_str() # for simplicity, we only define one operator that propagates expressions def __add__(self, other): temp = int( self ) + int( other ) if isinstance( self, NamedInt ) and isinstance( other, NamedInt ): return NamedInt( '({0} + {1})'.format(self.__name__, other.__name__), temp ) else: return temp x = NamedInt('the-x', 1 ) y = NamedInt('the-y', 2 ) # demonstrate that NamedInt propagates the names into an expression syntax print( repr( x ), repr( y ), repr( x+y )) from ref435 import Enum # requires redundant names, but loses names in the expression class NEI( NamedInt, Enum ): x = NamedInt('the-x', 1 ) y = NamedInt('the-y', 2 ) print( repr( NEI( 1 )), repr( NEI( 2 )), repr( NEI(1) + NEI(2))) # looks redundant, and still loses the names in the expression class NEI2( NamedInt, Enum ): x = x y = y print( repr( NEI2( x )), repr( NEI2( x )), repr( NEI2(x) + NEI2(y))) ___ 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] PEP 435 - reference implementation discussion
On 05/04/2013 08:50 PM, Tim Delaney wrote: Think I've come up with a system that works for my auto-numbering case without knowing the internals of enum_type. Patch passes all existing test cases. The patch does two things: 1. Finds the first non-Enum class on the MRO of the new class and uses that as the enum type. This is good. :) 2. Instead of directly setting the _name and _value of the enum_item, it lets the Enum class do it via Enum.__init__(). Subclasses can override this. This gives Enums a 2-phase construction just like other classes. Not sure I care for this. Enums are, at least in theory, immutable objects, and immutable objects don't call __init__. Of course, practicality beats purity... I'll have to think about this some more. Fortunately, none of this has any bearing on the PEP itself. -- ~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] PEP 435 - ref impl disc 2
On 5/4/2013 11:31 PM, Glenn Linderman wrote: So I have a class based on Nick's Named Values, that has been extended to propagate names into expressions, so that if you have named values 'x' and 'y', when you x + y, the result is a named value whose name is '(x + y)'. Seems pretty awkward to integrate this with Enum. Maybe I'm missing something. Here's carved down code with just one operator defined for brevity. The third item from each print statement should be the same, as far as I understand... but isn't. class NamedInt( int ): _count = 0 def __new__( cls, *args, **kwds ): name, *args = args if len( args ) == 0: args = [ cls._count ] cls._count += 1 self = super().__new__( cls, *args, **kwds ) self._name = name return self def __init__( self, *args, **kwds ): name, *args = args super().__init__() @property def __name__( self ): return self._name def __repr__( self ): # repr() is updated to include the name and type info return "{}({!r}, {})".format(type(self).__name__, self.__name__, super().__repr__()) def __str__( self ): # str() is unchanged, even if it relies on the repr() fallback base = super() base_str = base.__str__ if base_str.__objclass__ is object: return base.__repr__() return base_str() # for simplicity, we only define one operator that propagates expressions def __add__(self, other): temp = int( self ) + int( other ) if isinstance( self, NamedInt ) and isinstance( other, NamedInt ): return NamedInt( '({0} + {1})'.format(self.__name__, other.__name__), temp ) else: return temp x = NamedInt('the-x', 1 ) y = NamedInt('the-y', 2 ) # demonstrate that NamedInt propagates the names into an expression syntax print( repr( x ), repr( y ), repr( x+y )) from ref435 import Enum # requires redundant names, but loses names in the expression class NEI( NamedInt, Enum ): x = NamedInt('the-x', 1 ) y = NamedInt('the-y', 2 ) print( repr( NEI( 1 )), repr( NEI( 2 )), repr( NEI(1) + NEI(2))) # looks redundant, and still loses the names in the expression class NEI2( NamedInt, Enum ): x = x y = y print( repr( NEI2( x )), repr( NEI2( x )), repr( NEI2(x) + NEI2(y))) I've tried some more variations, without success: print( repr( NEI( x )), repr( NEI( y )), repr( NEI( x ) + NEI( y ))) print( repr( NEI.x ), repr( NEI.y ), repr( NEI.x + NEI.y)) print( repr( NEI2.x ), repr( NEI2.y ), repr( NEI2.x + NEI2.y )) Somehow, the overloading is not finding the __add__ operator in the NamedInt class, when the NamedInt's are wrapped in enumerations. ___ 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