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
0603d304
Kaydet (Commit)
0603d304
authored
Ock 06, 2015
tarafından
Raymond Hettinger
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #23132: Mitigate regression in speed and clarity in functools.total_ordering.
üst
212994e4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
80 additions
and
64 deletions
+80
-64
functools.py
Lib/functools.py
+78
-64
NEWS
Misc/NEWS
+2
-0
No files found.
Lib/functools.py
Dosyayı görüntüle @
0603d304
...
@@ -89,91 +89,106 @@ def wraps(wrapped,
...
@@ -89,91 +89,106 @@ def wraps(wrapped,
### total_ordering class decorator
### total_ordering class decorator
################################################################################
################################################################################
# The correct way to indicate that a comparison operation doesn't
# The total ordering functions all invoke the root magic method directly
# recognise the other type is to return NotImplemented and let the
# rather than using the corresponding operator. This avoids possible
# interpreter handle raising TypeError if both operands return
# infinite recursion that could occur when the operator dispatch logic
# NotImplemented from their respective comparison methods
# detects a NotImplemented result and then calls a reflected method.
#
# This makes the implementation of total_ordering more complicated, since
def
_gt_from_lt
(
self
,
other
):
# we need to be careful not to trigger infinite recursion when two
'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).'
# different types that both use this decorator encounter each other.
op_result
=
self
.
__lt__
(
other
)
#
if
op_result
is
NotImplemented
:
# For example, if a type implements __lt__, it's natural to define
return
NotImplemented
# __gt__ as something like:
return
not
op_result
and
self
!=
other
#
# lambda self, other: not self < other and not self == other
def
_le_from_lt
(
self
,
other
):
#
'Return a <= b. Computed by @total_ordering from (a < b) or (a == b).'
# However, using the operator syntax like that ends up invoking the full
op_result
=
self
.
__lt__
(
other
)
# type checking machinery again and means we can end up bouncing back and
return
op_result
or
self
==
other
# forth between the two operands until we run out of stack space.
#
def
_ge_from_lt
(
self
,
other
):
# The solution is to define helper functions that invoke the appropriate
'Return a >= b. Computed by @total_ordering from (not a < b).'
# magic methods directly, ensuring we only try each operand once, and
op_result
=
self
.
__lt__
(
other
)
# return NotImplemented immediately if it is returned from the
# underlying user provided method. Using this scheme, the __gt__ derived
# from a user provided __lt__ becomes:
#
# lambda self, other: _not_op_and_not_eq(self.__lt__, self, other))
def
_not_op
(
op
,
other
):
# "not a < b" handles "a >= b"
# "not a <= b" handles "a > b"
# "not a >= b" handles "a < b"
# "not a > b" handles "a <= b"
op_result
=
op
(
other
)
if
op_result
is
NotImplemented
:
if
op_result
is
NotImplemented
:
return
NotImplemented
return
NotImplemented
return
not
op_result
return
not
op_result
def
_op_or_eq
(
op
,
self
,
other
):
def
_ge_from_le
(
self
,
other
):
# "a < b or a == b" handles "a <= b"
'Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).'
# "a > b or a == b" handles "a >= b"
op_result
=
self
.
__le__
(
other
)
op_result
=
op
(
other
)
if
op_result
is
NotImplemented
:
if
op_result
is
NotImplemented
:
return
NotImplemented
return
NotImplemented
return
op_result
or
self
==
other
return
not
op_result
or
self
==
other
def
_lt_from_le
(
self
,
other
):
'Return a < b. Computed by @total_ordering from (a <= b) and (a != b).'
op_result
=
self
.
__le__
(
other
)
if
op_result
is
NotImplemented
:
return
NotImplemented
return
op_result
and
self
!=
other
def
_gt_from_le
(
self
,
other
):
'Return a > b. Computed by @total_ordering from (not a <= b).'
op_result
=
self
.
__le__
(
other
)
if
op_result
is
NotImplemented
:
return
NotImplemented
return
not
op_result
def
_not_op_and_not_eq
(
op
,
self
,
other
):
def
_lt_from_gt
(
self
,
other
):
# "not (a < b or a == b)" handles "a > b"
'Return a < b. Computed by @total_ordering from (not a > b) and (a != b).'
# "not a < b and a != b" is equivalent
op_result
=
self
.
__gt__
(
other
)
# "not (a > b or a == b)" handles "a < b"
# "not a > b and a != b" is equivalent
op_result
=
op
(
other
)
if
op_result
is
NotImplemented
:
if
op_result
is
NotImplemented
:
return
NotImplemented
return
NotImplemented
return
not
op_result
and
self
!=
other
return
not
op_result
and
self
!=
other
def
_not_op_or_eq
(
op
,
self
,
other
):
def
_ge_from_gt
(
self
,
other
):
# "not a <= b or a == b" handles "a >= b"
'Return a >= b. Computed by @total_ordering from (a > b) or (a == b).'
# "not a >= b or a == b" handles "a <= b"
op_result
=
self
.
__gt__
(
other
)
op_result
=
op
(
other
)
return
op_result
or
self
==
other
def
_le_from_gt
(
self
,
other
):
'Return a <= b. Computed by @total_ordering from (not a > b).'
op_result
=
self
.
__gt__
(
other
)
if
op_result
is
NotImplemented
:
return
NotImplemented
return
not
op_result
def
_le_from_ge
(
self
,
other
):
'Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).'
op_result
=
self
.
__ge__
(
other
)
if
op_result
is
NotImplemented
:
if
op_result
is
NotImplemented
:
return
NotImplemented
return
NotImplemented
return
not
op_result
or
self
==
other
return
not
op_result
or
self
==
other
def
_op_and_not_eq
(
op
,
self
,
other
):
def
_gt_from_ge
(
self
,
other
):
# "a <= b and not a == b" handles "a < b"
'Return a > b. Computed by @total_ordering from (a >= b) and (a != b).'
# "a >= b and not a == b" handles "a > b"
op_result
=
self
.
__ge__
(
other
)
op_result
=
op
(
other
)
if
op_result
is
NotImplemented
:
if
op_result
is
NotImplemented
:
return
NotImplemented
return
NotImplemented
return
op_result
and
self
!=
other
return
op_result
and
self
!=
other
def
_lt_from_ge
(
self
,
other
):
'Return a < b. Computed by @total_ordering from (not a >= b).'
op_result
=
self
.
__ge__
(
other
)
if
op_result
is
NotImplemented
:
return
NotImplemented
return
not
op_result
def
total_ordering
(
cls
):
def
total_ordering
(
cls
):
"""Class decorator that fills in missing ordering methods"""
"""Class decorator that fills in missing ordering methods"""
convert
=
{
convert
=
{
'__lt__'
:
[(
'__gt__'
,
lambda
self
,
other
:
_not_op_and_not_eq
(
self
.
__lt__
,
self
,
other
)
),
'__lt__'
:
[(
'__gt__'
,
_gt_from_lt
),
(
'__le__'
,
lambda
self
,
other
:
_op_or_eq
(
self
.
__lt__
,
self
,
other
)
),
(
'__le__'
,
_le_from_lt
),
(
'__ge__'
,
lambda
self
,
other
:
_not_op
(
self
.
__lt__
,
other
)
)],
(
'__ge__'
,
_ge_from_lt
)],
'__le__'
:
[(
'__ge__'
,
lambda
self
,
other
:
_not_op_or_eq
(
self
.
__le__
,
self
,
other
)
),
'__le__'
:
[(
'__ge__'
,
_ge_from_le
),
(
'__lt__'
,
lambda
self
,
other
:
_op_and_not_eq
(
self
.
__le__
,
self
,
other
)
),
(
'__lt__'
,
_lt_from_le
),
(
'__gt__'
,
lambda
self
,
other
:
_not_op
(
self
.
__le__
,
other
)
)],
(
'__gt__'
,
_gt_from_le
)],
'__gt__'
:
[(
'__lt__'
,
lambda
self
,
other
:
_not_op_and_not_eq
(
self
.
__gt__
,
self
,
other
)
),
'__gt__'
:
[(
'__lt__'
,
_lt_from_gt
),
(
'__ge__'
,
lambda
self
,
other
:
_op_or_eq
(
self
.
__gt__
,
self
,
other
)
),
(
'__ge__'
,
_ge_from_gt
),
(
'__le__'
,
lambda
self
,
other
:
_not_op
(
self
.
__gt__
,
other
)
)],
(
'__le__'
,
_le_from_gt
)],
'__ge__'
:
[(
'__le__'
,
lambda
self
,
other
:
_not_op_or_eq
(
self
.
__ge__
,
self
,
other
)
),
'__ge__'
:
[(
'__le__'
,
_le_from_ge
),
(
'__gt__'
,
lambda
self
,
other
:
_op_and_not_eq
(
self
.
__ge__
,
self
,
other
)
),
(
'__gt__'
,
_gt_from_ge
),
(
'__lt__'
,
lambda
self
,
other
:
_not_op
(
self
.
__ge__
,
other
)
)]
(
'__lt__'
,
_lt_from_ge
)]
}
}
# Find user-defined comparisons (not those inherited from object).
# Find user-defined comparisons (not those inherited from object).
roots
=
[
op
for
op
in
convert
if
getattr
(
cls
,
op
,
None
)
is
not
getattr
(
object
,
op
,
None
)]
roots
=
[
op
for
op
in
convert
if
getattr
(
cls
,
op
,
None
)
is
not
getattr
(
object
,
op
,
None
)]
...
@@ -183,7 +198,6 @@ def total_ordering(cls):
...
@@ -183,7 +198,6 @@ def total_ordering(cls):
for
opname
,
opfunc
in
convert
[
root
]:
for
opname
,
opfunc
in
convert
[
root
]:
if
opname
not
in
roots
:
if
opname
not
in
roots
:
opfunc
.
__name__
=
opname
opfunc
.
__name__
=
opname
opfunc
.
__doc__
=
getattr
(
int
,
opname
)
.
__doc__
setattr
(
cls
,
opname
,
opfunc
)
setattr
(
cls
,
opname
,
opfunc
)
return
cls
return
cls
...
...
Misc/NEWS
Dosyayı görüntüle @
0603d304
...
@@ -47,6 +47,8 @@ Library
...
@@ -47,6 +47,8 @@ Library
- Issue #23111: In the ftplib, make ssl.PROTOCOL_SSLv23 the default protocol
- Issue #23111: In the ftplib, make ssl.PROTOCOL_SSLv23 the default protocol
version.
version.
- Issue #23132: Mitigate regression in speed and clarity in functools.total_ordering.
- Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(),
- Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(),
instead of reading /dev/urandom, to get pseudo-random bytes.
instead of reading /dev/urandom, to get pseudo-random bytes.
...
...
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