Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
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
django
Commits
56ab5f52
Kaydet (Commit)
56ab5f52
authored
Ock 12, 2014
tarafından
Florian Apolloner
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Sade Fark
Merge pull request #2163 from apollo13/signals
Signals
üst
1afe7488
7959aff8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
106 additions
and
103 deletions
+106
-103
MANIFEST.in
MANIFEST.in
+1
-0
dispatcher.py
django/dispatch/dispatcher.py
+36
-27
license.python.txt
django/dispatch/license.python.txt
+0
-0
saferef.py
django/dispatch/saferef.py
+0
-0
weakref_backports.py
django/dispatch/weakref_backports.py
+69
-0
test_saferef.py
tests/dispatch/tests/test_saferef.py
+0
-76
No files found.
MANIFEST.in
Dosyayı görüntüle @
56ab5f52
...
@@ -6,6 +6,7 @@ include MANIFEST.in
...
@@ -6,6 +6,7 @@ include MANIFEST.in
include django/contrib/gis/gdal/LICENSE
include django/contrib/gis/gdal/LICENSE
include django/contrib/gis/geos/LICENSE
include django/contrib/gis/geos/LICENSE
include django/dispatch/license.txt
include django/dispatch/license.txt
include django/dispatch/license.python.txt
recursive-include docs *
recursive-include docs *
recursive-include scripts *
recursive-include scripts *
recursive-include extras *
recursive-include extras *
...
...
django/dispatch/dispatcher.py
Dosyayı görüntüle @
56ab5f52
import
weakref
import
sys
import
threading
import
threading
import
weakref
from
django.dispatch
import
saferef
from
django.utils.six.moves
import
xrange
from
django.utils.six.moves
import
xrange
if
sys
.
version_info
<
(
3
,
4
):
WEAKREF_TYPES
=
(
weakref
.
ReferenceType
,
saferef
.
BoundMethodWeakref
)
from
.weakref_backports
import
WeakMethod
else
:
from
weakref
import
WeakMethod
def
_make_id
(
target
):
def
_make_id
(
target
):
...
@@ -57,9 +59,7 @@ class Signal(object):
...
@@ -57,9 +59,7 @@ class Signal(object):
A function or an instance method which is to receive signals.
A function or an instance method which is to receive signals.
Receivers must be hashable objects.
Receivers must be hashable objects.
If weak is True, then receiver must be weak-referencable (more
If weak is True, then receiver must be weak-referencable.
precisely saferef.safeRef() must be able to create a reference
to the receiver).
Receivers must be able to accept keyword arguments.
Receivers must be able to accept keyword arguments.
...
@@ -105,20 +105,33 @@ class Signal(object):
...
@@ -105,20 +105,33 @@ class Signal(object):
assert
argspec
[
2
]
is
not
None
,
\
assert
argspec
[
2
]
is
not
None
,
\
"Signal receivers must accept keyword arguments (**kwargs)."
"Signal receivers must accept keyword arguments (**kwargs)."
receiver_id
=
_make_id
(
receiver
)
if
dispatch_uid
:
if
dispatch_uid
:
lookup_key
=
(
dispatch_uid
,
_make_id
(
sender
))
lookup_key
=
(
dispatch_uid
,
_make_id
(
sender
))
else
:
else
:
lookup_key
=
(
_make_id
(
receiver
)
,
_make_id
(
sender
))
lookup_key
=
(
receiver_id
,
_make_id
(
sender
))
if
weak
:
if
weak
:
receiver
=
saferef
.
safeRef
(
receiver
,
onDelete
=
self
.
_remove_receiver
)
ref
=
weakref
.
ref
original_receiver
=
receiver
# Check for bound methods
if
hasattr
(
receiver
,
'__self__'
)
and
hasattr
(
receiver
,
'__func__'
):
ref
=
WeakMethod
original_receiver
=
original_receiver
.
__self__
if
sys
.
version_info
>=
(
3
,
4
):
receiver
=
ref
(
receiver
)
weakref
.
finalize
(
original_receiver
,
self
.
_remove_receiver
,
receiver_id
=
receiver_id
)
else
:
receiver
=
ref
(
receiver
,
self
.
_remove_receiver
)
# Use the id of the weakref, since that's what passed to the weakref callback!
receiver_id
=
_make_id
(
receiver
)
with
self
.
lock
:
with
self
.
lock
:
for
r_key
,
_
in
self
.
receivers
:
for
r_key
,
_
,
_
in
self
.
receivers
:
if
r_key
==
lookup_key
:
if
r_key
==
lookup_key
:
break
break
else
:
else
:
self
.
receivers
.
append
((
lookup_key
,
receiver
))
self
.
receivers
.
append
((
lookup_key
,
receiver
,
receiver_id
))
self
.
sender_receivers_cache
.
clear
()
self
.
sender_receivers_cache
.
clear
()
def
disconnect
(
self
,
receiver
=
None
,
sender
=
None
,
weak
=
True
,
dispatch_uid
=
None
):
def
disconnect
(
self
,
receiver
=
None
,
sender
=
None
,
weak
=
True
,
dispatch_uid
=
None
):
...
@@ -150,7 +163,7 @@ class Signal(object):
...
@@ -150,7 +163,7 @@ class Signal(object):
with
self
.
lock
:
with
self
.
lock
:
for
index
in
xrange
(
len
(
self
.
receivers
)):
for
index
in
xrange
(
len
(
self
.
receivers
)):
(
r_key
,
_
)
=
self
.
receivers
[
index
]
(
r_key
,
_
,
_
)
=
self
.
receivers
[
index
]
if
r_key
==
lookup_key
:
if
r_key
==
lookup_key
:
del
self
.
receivers
[
index
]
del
self
.
receivers
[
index
]
break
break
...
@@ -242,7 +255,7 @@ class Signal(object):
...
@@ -242,7 +255,7 @@ class Signal(object):
with
self
.
lock
:
with
self
.
lock
:
senderkey
=
_make_id
(
sender
)
senderkey
=
_make_id
(
sender
)
receivers
=
[]
receivers
=
[]
for
(
receiverkey
,
r_senderkey
),
receiver
in
self
.
receivers
:
for
(
receiverkey
,
r_senderkey
),
receiver
,
_
in
self
.
receivers
:
if
r_senderkey
==
NONE_ID
or
r_senderkey
==
senderkey
:
if
r_senderkey
==
NONE_ID
or
r_senderkey
==
senderkey
:
receivers
.
append
(
receiver
)
receivers
.
append
(
receiver
)
if
self
.
use_caching
:
if
self
.
use_caching
:
...
@@ -253,7 +266,7 @@ class Signal(object):
...
@@ -253,7 +266,7 @@ class Signal(object):
self
.
sender_receivers_cache
[
sender
]
=
receivers
self
.
sender_receivers_cache
[
sender
]
=
receivers
non_weak_receivers
=
[]
non_weak_receivers
=
[]
for
receiver
in
receivers
:
for
receiver
in
receivers
:
if
isinstance
(
receiver
,
WEAKREF_TYPES
):
if
isinstance
(
receiver
,
weakref
.
ReferenceType
):
# Dereference the weak reference.
# Dereference the weak reference.
receiver
=
receiver
()
receiver
=
receiver
()
if
receiver
is
not
None
:
if
receiver
is
not
None
:
...
@@ -262,23 +275,19 @@ class Signal(object):
...
@@ -262,23 +275,19 @@ class Signal(object):
non_weak_receivers
.
append
(
receiver
)
non_weak_receivers
.
append
(
receiver
)
return
non_weak_receivers
return
non_weak_receivers
def
_remove_receiver
(
self
,
receiver
):
def
_remove_receiver
(
self
,
receiver
=
None
,
receiver_id
=
None
,
_make_id
=
_make_id
):
"""
"""
Remove dead receivers from connections.
Remove dead receivers from connections.
"""
`receiver_id` is used by python 3.4 and up. `receiver` is used in older
versions and is the weakref to the receiver (if the connection was defined
as `weak`). We also need to pass on `_make_id` since the original reference
will be None during module shutdown.
"""
with
self
.
lock
:
with
self
.
lock
:
to_remove
=
[]
if
receiver
is
not
None
:
for
key
,
connected_receiver
in
self
.
receivers
:
receiver_id
=
_make_id
(
receiver
)
if
connected_receiver
==
receiver
:
self
.
receivers
[:]
=
[
val
for
val
in
self
.
receivers
if
val
[
2
]
!=
receiver_id
]
to_remove
.
append
(
key
)
for
key
in
to_remove
:
last_idx
=
len
(
self
.
receivers
)
-
1
# enumerate in reverse order so that indexes are valid even
# after we delete some items
for
idx
,
(
r_key
,
_
)
in
enumerate
(
reversed
(
self
.
receivers
)):
if
r_key
==
key
:
del
self
.
receivers
[
last_idx
-
idx
]
self
.
sender_receivers_cache
.
clear
()
self
.
sender_receivers_cache
.
clear
()
...
...
django/dispatch/license.python.txt
0 → 100644
Dosyayı görüntüle @
56ab5f52
This diff is collapsed.
Click to expand it.
django/dispatch/saferef.py
deleted
100644 → 0
Dosyayı görüntüle @
1afe7488
This diff is collapsed.
Click to expand it.
django/dispatch/weakref_backports.py
0 → 100644
Dosyayı görüntüle @
56ab5f52
"""
weakref_backports is a partial backport of the weakref module for python
versions below 3.4.
Copyright (C) 2013 Python Software Foundation, see license.python.txt for
details.
The following changes were made to the original sources during backporting:
* Added `self` to `super` calls.
* Removed `from None` when raising exceptions.
"""
from
weakref
import
ref
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
)))
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
(
WeakMethod
,
self
)
.
__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__
tests/dispatch/tests/test_saferef.py
deleted
100644 → 0
Dosyayı görüntüle @
1afe7488
import
unittest
from
django.dispatch.saferef
import
safeRef
from
django.utils.six.moves
import
xrange
class
Test1
(
object
):
def
x
(
self
):
pass
def
test2
(
obj
):
pass
class
Test2
(
object
):
def
__call__
(
self
,
obj
):
pass
class
SaferefTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
ts
=
[]
ss
=
[]
for
x
in
xrange
(
5000
):
t
=
Test1
()
ts
.
append
(
t
)
s
=
safeRef
(
t
.
x
,
self
.
_closure
)
ss
.
append
(
s
)
ts
.
append
(
test2
)
ss
.
append
(
safeRef
(
test2
,
self
.
_closure
))
for
x
in
xrange
(
30
):
t
=
Test2
()
ts
.
append
(
t
)
s
=
safeRef
(
t
,
self
.
_closure
)
ss
.
append
(
s
)
self
.
ts
=
ts
self
.
ss
=
ss
self
.
closureCount
=
0
def
tearDown
(
self
):
del
self
.
ts
del
self
.
ss
def
testIn
(
self
):
"""Test the "in" operator for safe references (cmp)"""
for
t
in
self
.
ts
[:
50
]:
self
.
assertTrue
(
safeRef
(
t
.
x
)
in
self
.
ss
)
def
testValid
(
self
):
"""Test that the references are valid (return instance methods)"""
for
s
in
self
.
ss
:
self
.
assertTrue
(
s
())
def
testShortCircuit
(
self
):
"""Test that creation short-circuits to reuse existing references"""
sd
=
{}
for
s
in
self
.
ss
:
sd
[
s
]
=
1
for
t
in
self
.
ts
:
if
hasattr
(
t
,
'x'
):
self
.
assertTrue
(
safeRef
(
t
.
x
)
in
sd
)
else
:
self
.
assertTrue
(
safeRef
(
t
)
in
sd
)
def
testRepresentation
(
self
):
"""Test that the reference object's representation works
XXX Doesn't currently check the results, just that no error
is raised
"""
repr
(
self
.
ss
[
-
1
])
def
_closure
(
self
,
ref
):
"""Dumb utility mechanism to increment deletion counter"""
self
.
closureCount
+=
1
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