Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
101e0746
Kaydet (Commit)
101e0746
authored
Eyl 15, 2013
tarafından
Ethan Furman
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
üst
defe7f4c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
53 additions
and
26 deletions
+53
-26
enum.rst
Doc/library/enum.rst
+6
-0
enum.py
Lib/enum.py
+21
-15
test_enum.py
Lib/test/test_enum.py
+26
-11
No files found.
Doc/library/enum.rst
Dosyayı görüntüle @
101e0746
...
...
@@ -154,6 +154,12 @@ return A::
>>> Shape(2)
<Shape.square: 2>
.. note::
Attempting to create a member with the same name as an already
defined attribute (another member, a method, etc.) or attempting to create
an attribute with the same name as a member is not allowed.
Ensuring unique enumeration values
----------------------------------
...
...
Lib/enum.py
Dosyayı görüntüle @
101e0746
...
...
@@ -29,6 +29,14 @@ class _RouteClassAttributeToGetattr:
raise
AttributeError
(
"can't delete attribute"
)
def
_is_descriptor
(
obj
):
"""Returns True if obj is a descriptor, False otherwise."""
return
(
hasattr
(
obj
,
'__get__'
)
or
hasattr
(
obj
,
'__set__'
)
or
hasattr
(
obj
,
'__delete__'
))
def
_is_dunder
(
name
):
"""Returns True if a __dunder__ name, False otherwise."""
return
(
name
[:
2
]
==
name
[
-
2
:]
==
'__'
and
...
...
@@ -50,8 +58,9 @@ def _make_class_unpicklable(cls):
cls
.
__reduce__
=
_break_on_call_reduce
cls
.
__module__
=
'<unknown>'
class
_EnumDict
(
dict
):
"""
Keeps track of definition order of the enum items
.
"""
Track enum member order and ensure member names are not reused
.
EnumMeta will use the names found in self._member_names as the
enumeration member names.
...
...
@@ -62,11 +71,7 @@ class _EnumDict(dict):
self
.
_member_names
=
[]
def
__setitem__
(
self
,
key
,
value
):
"""Changes anything not dundered or that doesn't have __get__.
If a descriptor is added with the same name as an enum member, the name
is removed from _member_names (this may leave a hole in the numerical
sequence of values).
"""Changes anything not dundered or not a descriptor.
If an enum member name is used twice, an error is raised; duplicate
values are not checked for.
...
...
@@ -76,19 +81,20 @@ class _EnumDict(dict):
"""
if
_is_sunder
(
key
):
raise
ValueError
(
'_names_ are reserved for future Enum use'
)
elif
_is_dunder
(
key
)
or
hasattr
(
value
,
'__get__'
)
:
if
key
in
self
.
_member_names
:
# overwriting an enum with a method? then remove the name from
# _member_names or it will become an enum anyway when the class
# is created
self
.
_member_names
.
remove
(
key
)
else
:
if
key
in
self
.
_member_names
:
raise
TypeError
(
'
Attempted to reuse key:
%
r'
%
key
)
elif
_is_dunder
(
key
):
pass
elif
key
in
self
.
_member_names
:
# descriptor overwriting an enum?
raise
TypeError
(
'Attempted to reuse key:
%
r'
%
key
)
elif
not
_is_descriptor
(
value
):
if
key
in
self
:
# enum overwriting a descriptor?
raise
TypeError
(
'
Key already defined as:
%
r'
%
self
[
key
]
)
self
.
_member_names
.
append
(
key
)
super
()
.
__setitem__
(
key
,
value
)
# Dummy value for Enum as EnumMeta explicitly checks for it, but of course
# until EnumMeta finishes running the first time the Enum class doesn't exist.
# This is also why there are checks in EnumMeta like `if Enum is not None`
...
...
Lib/test/test_enum.py
Dosyayı görüntüle @
101e0746
...
...
@@ -228,6 +228,32 @@ class TestEnum(unittest.TestCase):
[
'FALL'
,
'ANOTHER_SPRING'
],
)
def
test_duplicate_name
(
self
):
with
self
.
assertRaises
(
TypeError
):
class
Color
(
Enum
):
red
=
1
green
=
2
blue
=
3
red
=
4
with
self
.
assertRaises
(
TypeError
):
class
Color
(
Enum
):
red
=
1
green
=
2
blue
=
3
def
red
(
self
):
return
'red'
with
self
.
assertRaises
(
TypeError
):
class
Color
(
Enum
):
@property
def
red
(
self
):
return
'redder'
red
=
1
green
=
2
blue
=
3
def
test_enum_with_value_name
(
self
):
class
Huh
(
Enum
):
name
=
1
...
...
@@ -618,17 +644,6 @@ class TestEnum(unittest.TestCase):
self
.
assertIsNot
(
type
(
whatever
.
really
),
whatever
)
self
.
assertEqual
(
whatever
.
this
.
really
(),
'no, not that'
)
def
test_overwrite_enums
(
self
):
class
Why
(
Enum
):
question
=
1
answer
=
2
propisition
=
3
def
question
(
self
):
print
(
42
)
self
.
assertIsNot
(
type
(
Why
.
question
),
Why
)
self
.
assertNotIn
(
Why
.
question
,
Why
.
_member_names_
)
self
.
assertNotIn
(
Why
.
question
,
Why
)
def
test_wrong_inheritance_order
(
self
):
with
self
.
assertRaises
(
TypeError
):
class
Wrong
(
Enum
,
str
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment