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
c3afba10
Kaydet (Commit)
c3afba10
authored
Kas 17, 2012
tarafından
Antoine Pitrou
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
üst
25bbe5e0
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
227 additions
and
1 deletion
+227
-1
weakref.rst
Doc/library/weakref.rst
+29
-0
test_weakref.py
Lib/test/test_weakref.py
+140
-0
weakref.py
Lib/weakref.py
+55
-1
NEWS
Misc/NEWS
+3
-0
No files found.
Doc/library/weakref.rst
Dosyayı görüntüle @
c3afba10
...
...
@@ -192,6 +192,35 @@ These method have the same issues as the and :meth:`keyrefs` method of
discarded when no strong reference to it exists any more.
.. class:: WeakMethod(method)
A custom :class:`ref` subclass which simulates a weak reference to a bound
method (i.e., a method defined on a class and looked up on an instance).
Since a bound method is ephemeral, a standard weak reference cannot keep
hold of it. :class:`WeakMethod` has special code to recreate the bound
method until either the object or the original function dies::
>>> class C:
... def method(self):
... print("method called!")
...
>>> c = C()
>>> r = weakref.ref(c.method)
>>> r()
>>> r = weakref.WeakMethod(c.method)
>>> r()
<bound method C.method of <__main__.C object at 0x7fc859830220>>
>>> r()()
method called!
>>> del c
>>> gc.collect()
0
>>> r()
>>>
.. versionadded:: 3.4
.. data:: ReferenceType
The type object for weak references objects.
...
...
Lib/test/test_weakref.py
Dosyayı görüntüle @
c3afba10
...
...
@@ -47,6 +47,11 @@ class Object:
return
NotImplemented
def
__hash__
(
self
):
return
hash
(
self
.
arg
)
def
some_method
(
self
):
return
4
def
other_method
(
self
):
return
5
class
RefCycle
:
def
__init__
(
self
):
...
...
@@ -880,6 +885,140 @@ class SubclassableWeakrefTestCase(TestBase):
self
.
assertEqual
(
self
.
cbcalled
,
0
)
class
WeakMethodTestCase
(
unittest
.
TestCase
):
def
_subclass
(
self
):
"""Return a Object subclass overriding `some_method`."""
class
C
(
Object
):
def
some_method
(
self
):
return
6
return
C
def
test_alive
(
self
):
o
=
Object
(
1
)
r
=
weakref
.
WeakMethod
(
o
.
some_method
)
self
.
assertIsInstance
(
r
,
weakref
.
ReferenceType
)
self
.
assertIsInstance
(
r
(),
type
(
o
.
some_method
))
self
.
assertIs
(
r
()
.
__self__
,
o
)
self
.
assertIs
(
r
()
.
__func__
,
o
.
some_method
.
__func__
)
self
.
assertEqual
(
r
()(),
4
)
def
test_object_dead
(
self
):
o
=
Object
(
1
)
r
=
weakref
.
WeakMethod
(
o
.
some_method
)
del
o
gc
.
collect
()
self
.
assertIs
(
r
(),
None
)
def
test_method_dead
(
self
):
C
=
self
.
_subclass
()
o
=
C
(
1
)
r
=
weakref
.
WeakMethod
(
o
.
some_method
)
del
C
.
some_method
gc
.
collect
()
self
.
assertIs
(
r
(),
None
)
def
test_callback_when_object_dead
(
self
):
# Test callback behaviour when object dies first.
C
=
self
.
_subclass
()
calls
=
[]
def
cb
(
arg
):
calls
.
append
(
arg
)
o
=
C
(
1
)
r
=
weakref
.
WeakMethod
(
o
.
some_method
,
cb
)
del
o
gc
.
collect
()
self
.
assertEqual
(
calls
,
[
r
])
# Callback is only called once.
C
.
some_method
=
Object
.
some_method
gc
.
collect
()
self
.
assertEqual
(
calls
,
[
r
])
def
test_callback_when_method_dead
(
self
):
# Test callback behaviour when method dies first.
C
=
self
.
_subclass
()
calls
=
[]
def
cb
(
arg
):
calls
.
append
(
arg
)
o
=
C
(
1
)
r
=
weakref
.
WeakMethod
(
o
.
some_method
,
cb
)
del
C
.
some_method
gc
.
collect
()
self
.
assertEqual
(
calls
,
[
r
])
# Callback is only called once.
del
o
gc
.
collect
()
self
.
assertEqual
(
calls
,
[
r
])
@support.cpython_only
def
test_no_cycles
(
self
):
# A WeakMethod doesn't create any reference cycle to itself.
o
=
Object
(
1
)
def
cb
(
_
):
pass
r
=
weakref
.
WeakMethod
(
o
.
some_method
,
cb
)
wr
=
weakref
.
ref
(
r
)
del
r
self
.
assertIs
(
wr
(),
None
)
def
test_equality
(
self
):
def
_eq
(
a
,
b
):
self
.
assertTrue
(
a
==
b
)
self
.
assertFalse
(
a
!=
b
)
def
_ne
(
a
,
b
):
self
.
assertTrue
(
a
!=
b
)
self
.
assertFalse
(
a
==
b
)
x
=
Object
(
1
)
y
=
Object
(
1
)
a
=
weakref
.
WeakMethod
(
x
.
some_method
)
b
=
weakref
.
WeakMethod
(
y
.
some_method
)
c
=
weakref
.
WeakMethod
(
x
.
other_method
)
d
=
weakref
.
WeakMethod
(
y
.
other_method
)
# Objects equal, same method
_eq
(
a
,
b
)
_eq
(
c
,
d
)
# Objects equal, different method
_ne
(
a
,
c
)
_ne
(
a
,
d
)
_ne
(
b
,
c
)
_ne
(
b
,
d
)
# Objects unequal, same or different method
z
=
Object
(
2
)
e
=
weakref
.
WeakMethod
(
z
.
some_method
)
f
=
weakref
.
WeakMethod
(
z
.
other_method
)
_ne
(
a
,
e
)
_ne
(
a
,
f
)
_ne
(
b
,
e
)
_ne
(
b
,
f
)
del
x
,
y
,
z
gc
.
collect
()
# Dead WeakMethods compare by identity
refs
=
a
,
b
,
c
,
d
,
e
,
f
for
q
in
refs
:
for
r
in
refs
:
self
.
assertEqual
(
q
==
r
,
q
is
r
)
self
.
assertEqual
(
q
!=
r
,
q
is
not
r
)
def
test_hashing
(
self
):
# Alive WeakMethods are hashable if the underlying object is
# hashable.
x
=
Object
(
1
)
y
=
Object
(
1
)
a
=
weakref
.
WeakMethod
(
x
.
some_method
)
b
=
weakref
.
WeakMethod
(
y
.
some_method
)
c
=
weakref
.
WeakMethod
(
y
.
other_method
)
# Since WeakMethod objects are equal, the hashes should be equal.
self
.
assertEqual
(
hash
(
a
),
hash
(
b
))
ha
=
hash
(
a
)
# Dead WeakMethods retain their old hash value
del
x
,
y
gc
.
collect
()
self
.
assertEqual
(
hash
(
a
),
ha
)
self
.
assertEqual
(
hash
(
b
),
ha
)
# If it wasn't hashed when alive, a dead WeakMethod cannot be hashed.
self
.
assertRaises
(
TypeError
,
hash
,
c
)
class
MappingTestCase
(
TestBase
):
COUNT
=
10
...
...
@@ -1455,6 +1594,7 @@ __test__ = {'libreftest' : libreftest}
def
test_main
():
support
.
run_unittest
(
ReferencesTestCase
,
WeakMethodTestCase
,
MappingTestCase
,
WeakValueDictionaryTestCase
,
WeakKeyDictionaryTestCase
,
...
...
Lib/weakref.py
Dosyayı görüntüle @
c3afba10
...
...
@@ -27,7 +27,61 @@ ProxyTypes = (ProxyType, CallableProxyType)
__all__
=
[
"ref"
,
"proxy"
,
"getweakrefcount"
,
"getweakrefs"
,
"WeakKeyDictionary"
,
"ReferenceType"
,
"ProxyType"
,
"CallableProxyType"
,
"ProxyTypes"
,
"WeakValueDictionary"
,
"WeakSet"
]
"WeakSet"
,
"WeakMethod"
]
class
WeakMethod
(
ref
):
"""
A custom `weakref.ref` subclass which simulates a weak reference to
a bound method, working around the lifetime problem of bound methods.
"""
__slots__
=
"_func_ref"
,
"_meth_type"
,
"_alive"
,
"__weakref__"
def
__new__
(
cls
,
meth
,
callback
=
None
):
try
:
obj
=
meth
.
__self__
func
=
meth
.
__func__
except
AttributeError
:
raise
TypeError
(
"argument should be a bound method, not {}"
.
format
(
type
(
meth
)))
from
None
def
_cb
(
arg
):
# The self-weakref trick is needed to avoid creating a reference
# cycle.
self
=
self_wr
()
if
self
.
_alive
:
self
.
_alive
=
False
if
callback
is
not
None
:
callback
(
self
)
self
=
ref
.
__new__
(
cls
,
obj
,
_cb
)
self
.
_func_ref
=
ref
(
func
,
_cb
)
self
.
_meth_type
=
type
(
meth
)
self
.
_alive
=
True
self_wr
=
ref
(
self
)
return
self
def
__call__
(
self
):
obj
=
super
()
.
__call__
()
func
=
self
.
_func_ref
()
if
obj
is
None
or
func
is
None
:
return
None
return
self
.
_meth_type
(
func
,
obj
)
def
__eq__
(
self
,
other
):
if
isinstance
(
other
,
WeakMethod
):
if
not
self
.
_alive
or
not
other
.
_alive
:
return
self
is
other
return
ref
.
__eq__
(
self
,
other
)
and
self
.
_func_ref
==
other
.
_func_ref
return
False
def
__ne__
(
self
,
other
):
if
isinstance
(
other
,
WeakMethod
):
if
not
self
.
_alive
or
not
other
.
_alive
:
return
self
is
not
other
return
ref
.
__ne__
(
self
,
other
)
or
self
.
_func_ref
!=
other
.
_func_ref
return
True
__hash__
=
ref
.
__hash__
class
WeakValueDictionary
(
collections
.
MutableMapping
):
...
...
Misc/NEWS
Dosyayı görüntüle @
c3afba10
...
...
@@ -127,6 +127,9 @@ Core and Builtins
Library
-------
- Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak
references to bound methods.
- Issue #16469: Fix exceptions from float -> Fraction and Decimal -> Fraction
conversions for special values to be consistent with those for float -> int
and Decimal -> int. Patch by Alexey Kachayev.
...
...
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