Antoine Pitrou added the comment:
The fact that derived_int.from_bytes() doesn't call the derived constructor
clearly sounds like a bug to me, regardless of whether IntEnum also has its own
bugs.
--
nosy: +pitrou
___
Python tracker
Ethan Furman added the comment:
With the patch:
-- import enum
-- class Huh(enum.IntEnum):
... blah = 2
...
-- Huh.blah.from_bytes(b'\04', 'big')
Traceback (most recent call last):
File stdin, line 1, in module
File /home/ethan/source/python/issue23640/Lib/enum.py, line
Serhiy Storchaka added the comment:
This bug allows to create new bool instances.
false = bool.from_bytes(b'\0', 'big')
true = bool.from_bytes(b'\1', 'big')
bool(false)
False
bool(true)
True
false is False
False
true is True
False
false
False
true
False
--
priority: normal -
Bruno Cauet added the comment:
I'm not sure how you can have both, those two seem opposite to me:
- if 'from_bytes' returns the same type as the class it is called on then
the instantiation of the result object should go through its constructor
(patch proposed)
- if the subclass should override
Ethan Furman added the comment:
'from_bytes' is a classmethod. As such, it should return the same type as the
class it is called on. If that wasn't the intent it would be a staticmethod
instead.
It is the responsibility of the subclass to override base class behavior, not
the other way
Bruno Cauet added the comment:
Hi,
I feel like this behaviour does not only affect IntEnum related but anything
that inherits from int.
Example:
class foo(int):
... def __init__(self, value, base=10):
... if value == 2:
... raise ValueError(not that!!)
...
Serhiy Storchaka added the comment:
Not all classmethods are constructors.
I see two solutions:
1) Override from_bytes() in IntEnum and every int subclass that needs this.
2) Change int.from_bytes() to call __new__.
--
___
Python tracker
Bruno Cauet added the comment:
I took the liberty of putting together a small patch which makes from_bytes()
call return type(value_found) if type != long (Serhiy's my 2nd solution).
Ethan: in that case, type.from_bytes() would always return an int, and not
resort to build-a-pseudo-int,
Changes by Ethan Furman et...@stoneleaf.us:
--
stage: - test needed
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue23640
___
___
Python-bugs-list
Ethan Furman added the comment:
The only solution that is coming to mind is to have EnumMeta go through the
other base classes, wrap any classmethods it finds, and ensure that they return
their appropriate type and not an Enum type.
Any other ideas?
--
Changes by Ethan Furman et...@stoneleaf.us:
--
keywords: +patch
stage: test needed - needs patch
Added file: http://bugs.python.org/file38444/issue23640.stoneleaf.01.patch
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue23640
Ethan Furman added the comment:
I think the classmethod-as-constructor behavior is correct, so it's up to
IntEnum (or EnumMeta, or foo, or ...), to work around the issue.
--
___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue23640
New submission from Serhiy Storchaka:
Example:
import socket
x = socket.AddressFamily.from_bytes(b'\1', 'big')
type(x)
enum 'AddressFamily'
int(x)
1
str(x)
Traceback (most recent call last):
File stdin, line 1, in module
File /home/serhiy/py/cpython/Lib/enum.py, line 464, in __str__
13 matches
Mail list logo