Skip to content

Commit d65aaf4

Browse files
committed
deprecate current behavior
1 parent 8769a2e commit d65aaf4

File tree

4 files changed

+77
-26
lines changed

4 files changed

+77
-26
lines changed

Doc/library/enum.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,10 @@ Utilities and Decorators
761761
``_generate_next_value_`` can be overridden to customize the values used by
762762
*auto*.
763763

764+
.. note:: in 3.13 the default ``"generate_next_value_`` will always return
765+
the highest member value incremented by 1, and will fail if any
766+
member is an incompatible type.
767+
764768
.. decorator:: property
765769

766770
A decorator similar to the built-in *property*, but specifically for

Lib/enum.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,28 +1205,39 @@ def __new__(cls, value):
12051205
def __init__(self, *args, **kwds):
12061206
pass
12071207

1208-
def _generate_next_value_(name, start, count, last_values):
1208+
def _generate_next_value_(name, start, count, last_value):
12091209
"""
12101210
Generate the next value when not given.
12111211
12121212
name: the name of the member
12131213
start: the initial start value or None
12141214
count: the number of existing members
1215-
last_values: the list of values assigned
1215+
last_value: the list of values assigned
12161216
"""
1217-
1218-
# Filter funciton to deal with last_values lists of mixed types
1219-
def test_incrementable(n):
1220-
try:
1221-
n + 1
1222-
return True
1223-
except TypeError:
1224-
return False
1225-
1226-
checked_last_values = sorted(filter(test_incrementable, last_values))
1227-
if checked_last_values:
1228-
return checked_last_values[-1] + 1
1229-
else:
1217+
if not last_value:
1218+
return start
1219+
try:
1220+
last = last_value[-1]
1221+
last_value.sort()
1222+
if last == last_value[-1]:
1223+
# no difference between old and new methods
1224+
return last + 1
1225+
else:
1226+
# trigger old method (with warning)
1227+
raise TypeError
1228+
except TypeError:
1229+
import warnings
1230+
warnings.warn(
1231+
"In 3.13 the default `auto()`/`_generate_next_value_` will require all values to be sortable and support adding +1\n"
1232+
"and the value returned will be the largest value in the enum incremented by 1",
1233+
DeprecationWarning,
1234+
stacklevel=3,
1235+
)
1236+
for v in last_value:
1237+
try:
1238+
return v + 1
1239+
except TypeError:
1240+
pass
12301241
return start
12311242

12321243
@classmethod

Lib/test/test_enum.py

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3953,23 +3953,54 @@ class Color(AutoNameEnum):
39533953
self.assertEqual(Color.blue.value, 'blue')
39543954
self.assertEqual(Color.green.value, 'green')
39553955

3956-
def test_auto_garbage(self):
3957-
class Color(Enum):
3958-
red = 'red'
3959-
blue = auto()
3956+
@unittest.skipIf(
3957+
python_version >= (3, 13),
3958+
'mixed types with auto() no longer supported',
3959+
)
3960+
def test_auto_garbage_ok(self):
3961+
with self.assertWarnsRegex(DeprecationWarning, 'will require all values to be sortable'):
3962+
class Color(Enum):
3963+
red = 'red'
3964+
blue = auto()
39603965
self.assertEqual(Color.blue.value, 1)
39613966

3962-
def test_auto_garbage_corrected(self):
3963-
class Color(Enum):
3964-
red = 'red'
3965-
blue = 2
3966-
green = auto()
3967+
@unittest.skipIf(
3968+
python_version >= (3, 13),
3969+
'mixed types with auto() no longer supported',
3970+
)
3971+
def test_auto_garbage_corrected_ok(self):
3972+
with self.assertWarnsRegex(DeprecationWarning, 'will require all values to be sortable'):
3973+
class Color(Enum):
3974+
red = 'red'
3975+
blue = 2
3976+
green = auto()
39673977

39683978
self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
39693979
self.assertEqual(Color.red.value, 'red')
39703980
self.assertEqual(Color.blue.value, 2)
39713981
self.assertEqual(Color.green.value, 3)
39723982

3983+
@unittest.skipIf(
3984+
python_version < (3, 13),
3985+
'mixed types with auto() will raise in 3.13',
3986+
)
3987+
def test_auto_garbage_fail(self):
3988+
with self.assertRaisesRegex(TypeError, 'will require all values to be sortable'):
3989+
class Color(Enum):
3990+
red = 'red'
3991+
blue = auto()
3992+
3993+
@unittest.skipIf(
3994+
python_version < (3, 13),
3995+
'mixed types with auto() will raise in 3.13',
3996+
)
3997+
def test_auto_garbage_corrected_fail(self):
3998+
with self.assertRaisesRegex(TypeError, 'will require all values to be sortable'):
3999+
class Color(Enum):
4000+
red = 'red'
4001+
blue = 2
4002+
green = auto()
4003+
39734004
def test_auto_order(self):
39744005
with self.assertRaises(TypeError):
39754006
class Color(Enum):
@@ -3991,6 +4022,10 @@ def _generate_next_value_(name, start, count, last):
39914022
self.assertEqual(Color.red.value, 'pathological case')
39924023
self.assertEqual(Color.blue.value, 'blue')
39934024

4025+
@unittest.skipIf(
4026+
python_version < (3, 13),
4027+
'auto() will return highest value + 1 in 3.13',
4028+
)
39944029
def test_auto_with_aliases(self):
39954030
class Color(Enum):
39964031
red = auto()
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
Fixed an issue with Enums where the default behavior of auto() was
2-
generating incorrect values following alias assignment
1+
Deprecate current default auto() behavior: In 3.13 the default will be for
2+
for auto() to always return the largest member value incremented by
3+
1, and to raise if incompatible value types are used.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy