[issue33437] Defining __init__ in enums

2019-01-09 Thread Cheryl Sabella


Change by Cheryl Sabella :


--
resolution:  -> fixed
stage: patch review -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue33437] Defining __init__ in enums

2018-09-12 Thread miss-islington


miss-islington  added the comment:


New changeset f52237400b9960d434c5d0676a3479b8c1e8c869 by Miss Islington (bot) 
(Ethan Furman) in branch 'master':
bpo-33437: add __new__ vs __init__ example (GH-9145)
https://github.com/python/cpython/commit/f52237400b9960d434c5d0676a3479b8c1e8c869


--
nosy: +miss-islington

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue33437] Defining __init__ in enums

2018-09-10 Thread Ethan Furman


Change by Ethan Furman :


--
pull_requests: +8593
stage:  -> patch review

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue33437] Defining __init__ in enums

2018-05-08 Thread Ethan Furman

Ethan Furman  added the comment:

That new example looks great!  Note that you don't need the parenthesis, though.

FYI: The same thing using the aenum library* would look like:

from aenum import Enum

class Coord(bytes, Enum):
_init_ = 'value label unit'

PX = [0], 'P.X', 'km'
PY = [1], 'P.Y', 'km'
VX = [2], 'V.X', 'km/s'
VY = [3], 'V.Y', 'km/s'


* aenum is the Advanced Enum library I wrote that has a few extra abilities.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue33437] Defining __init__ in enums

2018-05-08 Thread Andres Ayala

Andres Ayala  added the comment:

I see, with mixed types you need to use __new__ to construct the elements (I 
imagine is specially important for non mutable types)

I have modified the example of the coordinates to try to use a mixed type. Is 
not the most useful thing, but it mix the bytes class.
Is it not obvious how to correctly use the mixin + __new__ operator so it is 
easy that the example is not correct or can be done better.

class Coordinate(bytes, Enum):
"""
Coordinate with binary codes that can be indexed by the int code.
"""
def __new__(cls, value, label, unit):
obj = bytes.__new__(cls, [value])
obj._value_ = value
obj.label = label
obj.unit = unit
return obj

PX = (0, 'P.X', 'km')
PY = (1, 'P.Y', 'km')
VX = (2, 'V.X', 'km/s')
VY = (3, 'V.Y', 'km/s')


# This works as expected
for element in Coordinate:
print("{0}: {0.label}[{0.unit}] = {0.value}".format(element))

# And this Work
print("Obtain P.Y from the name:", Coordinate['PY'])
print("Obtain V.Y from the index:", Coordinate(3))

# This shall be False
print('Coordinate.PY == 1 is:', Coordinate.PY == 1)
# But this shall be True
print("Coordinate.PY == b'\\01' is:", Coordinate.PY == b'\01')

Thanks!

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue33437] Defining __init__ in enums

2018-05-07 Thread Ethan Furman

Ethan Furman  added the comment:

Setting _value_ needs to happen in __new__ for those cases where another data 
type, such as str or int, is mixed in.

I'll look at adding an example to the docs.

Thanks for the report!

--
assignee:  -> ethan.furman
components: +Documentation
nosy: +barry, eli.bendersky, ethan.furman
type: enhancement -> behavior
versions: +Python 3.7, Python 3.8

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue33437] Defining __init__ in enums

2018-05-07 Thread Andres Ayala

New submission from Andres Ayala :

I have to read and write many files for an old fortran program where the 
elements are coded as integer (so 0 is the X, 1 is the Y...) and I have some 
tags associated to each one.

So I tried to create an Enum with some additional fields:
class Coord(Enum):
def __init__(self, value, label, unit):
super().__init__()
self._value_ = value
self.label = label
self.unit = unit

PX = (0, 'P.X', 'km')
PY = (1, 'P.Y', 'km')
VX = (2, 'V.X', 'km/s')
VY = (3, 'V.Y', 'km/s')

This almost work:
>>> for element in CoordOk:
...print("{0}: {0.label}[{0.unit}] = {0.value}".format(element))
CoordOk.PX: P.X[km] = 0
CoordOk.PY: P.Y[km] = 1
CoordOk.VX: V.X[km/s] = 2
CoordOk.VY: V.Y[km/s] = 3

But fails recovering the coordinate from the value:
>>> print(Coord(0))
Traceback (most recent call last):
  File "/home/killerrex/tmp/demo.py", line 33, in 
print(Coord(0))
  File "/usr/lib64/python3.6/enum.py", line 291, in __call__
return cls.__new__(cls, value)
  File "/usr/lib64/python3.6/enum.py", line 533, in __new__
return cls._missing_(value)
  File "/usr/lib64/python3.6/enum.py", line 546, in _missing_
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 0 is not a valid Coord

Because the internal value of the enum is (0, 'P.X', 'km') and not 0

I found that it is possible to do what I am trying to do with:
class CoordOk(Enum):
def __new__(cls, value, label, unit):
obj = object.__new__(cls)
obj._value_ = value
obj.label = label
obj.unit = unit
return obj

PX = (0, 'P.X', 'km')
PY = (1, 'P.Y', 'km')
VX = (2, 'V.X', 'km/s')
VY = (3, 'V.Y', 'km/s')

Following the latest doc from Enum. Although it is not so intuitive (defining 
__new__ is not as easy as __init__)

To make the first proposal work fine is enough with moving the line 221 of 
enum.py after the line 224 (see the patch)
I haven't found problems with the change but obviously my little reduced tests 
are not representative at all.
And even if it works there may be good reasons to not allow changing the 
_value_ in the init.

So mi enhancement proposal is either:
Add an example like the CoordOk to the documentation to help others to find how 
to change the _value_ (and an explanation on why is better not to do it in the 
__init__ would be perfect)

or

Change the line enum.py so it is possible to update the _value_ in the __init__ 
method and if you want use the Coord example in the docs.

Thanks!

--
components: Library (Lib)
files: enum_allow_change_value_in_init.patch
keywords: patch
messages: 316256
nosy: killerrex
priority: normal
severity: normal
status: open
title: Defining __init__ in enums
type: enhancement
versions: Python 3.6
Added file: 
https://bugs.python.org/file47575/enum_allow_change_value_in_init.patch

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com