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
41deb1ef
Kaydet (Commit)
41deb1ef
authored
Şub 01, 2001
tarafından
Fred Drake
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
PEP 205, Weak References -- initial checkin.
üst
2de7471d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
401 additions
and
4 deletions
+401
-4
classobject.h
Include/classobject.h
+1
-0
object.h
Include/object.h
+5
-3
objimpl.h
Include/objimpl.h
+11
-1
test_weakref
Lib/test/output/test_weakref
+21
-0
test_weakref.py
Lib/test/test_weakref.py
+218
-0
weakref.py
Lib/weakref.py
+117
-0
_weakref.c
Modules/_weakref.c
+0
-0
classobject.c
Objects/classobject.c
+5
-0
object.c
Objects/object.c
+23
-0
No files found.
Include/classobject.h
Dosyayı görüntüle @
41deb1ef
...
...
@@ -24,6 +24,7 @@ typedef struct {
PyObject_HEAD
PyClassObject
*
in_class
;
/* The class object */
PyObject
*
in_dict
;
/* A dictionary */
PyObject
*
in_weakreflist
;
/* List of weak references */
}
PyInstanceObject
;
typedef
struct
{
...
...
Include/object.h
Dosyayı görüntüle @
41deb1ef
...
...
@@ -246,8 +246,8 @@ typedef struct _typeobject {
/* rich comparisons */
richcmpfunc
tp_richcompare
;
/*
More spares
*/
long
tp_
xxx8
;
/*
weak reference enabler
*/
long
tp_
weaklistoffset
;
#ifdef COUNT_ALLOCS
/* these must be last */
...
...
@@ -284,6 +284,8 @@ extern DL_IMPORT(int) PyCallable_Check(PyObject *);
extern
DL_IMPORT
(
int
)
PyNumber_Coerce
(
PyObject
**
,
PyObject
**
);
extern
DL_IMPORT
(
int
)
PyNumber_CoerceEx
(
PyObject
**
,
PyObject
**
);
extern
DL_IMPORT
(
int
)
(
*
PyObject_ClearWeakRefs
)(
PyObject
*
);
/* Helpers for printing recursive container types */
extern
DL_IMPORT
(
int
)
Py_ReprEnter
(
PyObject
*
);
extern
DL_IMPORT
(
void
)
Py_ReprLeave
(
PyObject
*
);
...
...
@@ -418,7 +420,7 @@ extern DL_IMPORT(long) _Py_RefTotal;
#define Py_INCREF(op) (_Py_RefTotal++, (op)->ob_refcnt++)
#define Py_DECREF(op) \
if (--_Py_RefTotal,
--(op)->ob_refcnt != 0
) \
if (--_Py_RefTotal,
(--((op)->ob_refcnt) != 0)
) \
; \
else \
_Py_Dealloc((PyObject *)(op))
...
...
Include/objimpl.h
Dosyayı görüntüle @
41deb1ef
...
...
@@ -160,7 +160,11 @@ extern DL_IMPORT(void) _PyObject_Del(PyObject *);
/* Macros trading binary compatibility for speed. See also pymem.h.
Note that these macros expect non-NULL object pointers.*/
#define PyObject_INIT(op, typeobj) \
( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
((op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), \
(PyType_SUPPORTS_WEAKREFS((typeobj)) \
? *(PyObject_GET_WEAKREFS_LISTPTR(op)) = NULL \
: NULL), \
(op))
#define PyObject_INIT_VAR(op, typeobj, size) \
( (op)->ob_size = (size), PyObject_INIT((op), (typeobj)) )
...
...
@@ -266,6 +270,12 @@ extern DL_IMPORT(void) _PyGC_Dump(PyGC_Head *);
#endif
/* WITH_CYCLE_GC */
/* Test if a type supports weak references */
#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
#define PyObject_GET_WEAKREFS_LISTPTR(o) \
((PyObject **) (((char *) (o)) + (o)->ob_type->tp_weaklistoffset))
#ifdef __cplusplus
}
#endif
...
...
Lib/test/output/test_weakref
0 → 100644
Dosyayı görüntüle @
41deb1ef
test_weakref
Basic Weak References
-- Liveness and referent identity
-- Reference objects with callbacks
-- Proxy objects with callbacks
-- Re-use of weak reference objects
reference objects
proxy objects
clearing ref 2
clearing ref 1
clearing ref 2
clearing ref 1
Weak Valued Dictionaries
objects are stored in weak dict
weak dict test complete
Non-callable Proxy References
XXX -- tests not written!
Callable Proxy References
Lib/test/test_weakref.py
0 → 100644
Dosyayı görüntüle @
41deb1ef
import
sys
import
weakref
from
test_support
import
TestFailed
,
verify
class
C
:
pass
print
"Basic Weak References"
print
"-- Liveness and referent identity"
o
=
C
()
ref
=
weakref
.
ref
(
o
)
verify
(
ref
()
is
not
None
,
"weak reference to live object should be live"
)
o2
=
ref
()
verify
(
ref
()
is
not
None
,
"weak ref should still be live"
)
verify
(
o
is
o2
,
"<ref>() should return original object if live"
)
del
o
,
o2
del
ref
cbcalled
=
0
def
callback
(
o
):
global
cbcalled
cbcalled
=
1
o
=
C
()
ref2
=
weakref
.
ref
(
o
,
callback
)
del
o
verify
(
cbcalled
,
"callback did not properly set 'cbcalled'"
)
verify
(
ref2
()
is
None
,
"ref2 should be dead after deleting object reference"
)
del
ref2
print
"-- Reference objects with callbacks"
o
=
C
()
o
.
bar
=
1
ref1
=
weakref
.
ref
(
o
,
id
)
ref2
=
weakref
.
ref
(
o
,
id
)
del
o
verify
(
ref1
()
is
None
,
"expected reference to be invalidated"
)
verify
(
ref2
()
is
None
,
"expected reference to be invalidated"
)
print
"-- Proxy objects with callbacks"
o
=
C
()
o
.
bar
=
1
ref1
=
weakref
.
proxy
(
o
,
id
)
ref2
=
weakref
.
proxy
(
o
,
id
)
del
o
try
:
ref1
.
bar
except
weakref
.
ReferenceError
:
pass
else
:
raise
TestFailed
(
"expected ReferenceError exception"
)
try
:
ref2
.
bar
except
weakref
.
ReferenceError
:
pass
else
:
raise
TestFailed
(
"expected ReferenceError exception"
)
print
"-- Re-use of weak reference objects"
print
" reference objects"
o
=
C
()
ref1
=
weakref
.
ref
(
o
)
# create a proxy to make sure that there's an intervening creation
# between these two; it should make no difference
proxy
=
weakref
.
proxy
(
o
)
ref2
=
weakref
.
ref
(
o
)
verify
(
ref1
is
ref2
,
"reference object w/out callback should have been re-used"
)
o
=
C
()
proxy
=
weakref
.
proxy
(
o
)
ref1
=
weakref
.
ref
(
o
)
ref2
=
weakref
.
ref
(
o
)
verify
(
ref1
is
ref2
,
"reference object w/out callback should have been re-used"
)
verify
(
weakref
.
getweakrefcount
(
o
)
==
2
,
"wrong weak ref count for object"
)
del
proxy
verify
(
weakref
.
getweakrefcount
(
o
)
==
1
,
"wrong weak ref count for object after deleting proxy"
)
print
" proxy objects"
o
=
C
()
ref3
=
weakref
.
proxy
(
o
)
ref4
=
weakref
.
proxy
(
o
)
verify
(
ref3
is
ref4
,
"proxy object w/out callback should have been re-used"
)
def
clearing1
(
r
):
print
"clearing ref 1"
def
clearing2
(
r
):
print
"clearing ref 2"
o
=
C
()
ref1
=
weakref
.
ref
(
o
,
clearing1
)
ref2
=
weakref
.
ref
(
o
,
clearing2
)
verify
(
weakref
.
getweakrefcount
(
o
)
==
2
,
"got wrong number of weak reference objects"
)
del
o
o
=
C
()
ref1
=
weakref
.
ref
(
o
,
clearing1
)
ref2
=
weakref
.
ref
(
o
,
clearing2
)
del
ref1
verify
(
weakref
.
getweakrefs
(
o
)
==
[
ref2
],
"list of refs does not match"
)
del
o
o
=
C
()
ref1
=
weakref
.
ref
(
o
,
clearing1
)
ref2
=
weakref
.
ref
(
o
,
clearing2
)
del
ref2
verify
(
weakref
.
getweakrefs
(
o
)
==
[
ref1
],
"list of refs does not match"
)
del
o
print
print
"Weak Valued Dictionaries"
class
Object
:
def
__init__
(
self
,
arg
):
self
.
arg
=
arg
def
__repr__
(
self
):
return
"<Object
%
r>"
%
self
.
arg
dict
=
weakref
.
mapping
()
objects
=
map
(
Object
,
range
(
10
))
for
o
in
objects
:
dict
[
o
.
arg
]
=
o
print
"objects are stored in weak dict"
for
o
in
objects
:
verify
(
weakref
.
getweakrefcount
(
o
)
==
1
,
"wrong number of weak references to
%
r!"
%
o
)
verify
(
o
is
dict
[
o
.
arg
],
"wrong object returned by weak dict!"
)
dict
.
clear
()
print
"weak dict test complete"
print
print
"Non-callable Proxy References"
print
"XXX -- tests not written!"
def
test_proxy
(
o
,
proxy
):
o
.
foo
=
1
verify
(
proxy
.
foo
==
1
,
"proxy does not reflect attribute addition"
)
o
.
foo
=
2
verify
(
proxy
.
foo
==
2
,
"proxy does not reflect attribute modification"
)
del
o
.
foo
verify
(
not
hasattr
(
proxy
,
'foo'
),
"proxy does not reflect attribute removal"
)
proxy
.
foo
=
1
verify
(
o
.
foo
==
1
,
"object does not reflect attribute addition via proxy"
)
proxy
.
foo
=
2
verify
(
o
.
foo
==
2
,
"object does not reflect attribute modification via proxy"
)
del
proxy
.
foo
verify
(
not
hasattr
(
o
,
'foo'
),
"object does not reflect attribute removal via proxy"
)
o
=
C
()
test_proxy
(
o
,
weakref
.
proxy
(
o
))
print
print
"Callable Proxy References"
class
Callable
:
bar
=
None
def
__call__
(
self
,
x
):
self
.
bar
=
x
o
=
Callable
()
ref1
=
weakref
.
proxy
(
o
)
test_proxy
(
o
,
ref1
)
verify
(
type
(
ref1
)
is
weakref
.
CallableProxyType
,
"proxy is not of callable type"
)
ref1
(
'twinkies!'
)
verify
(
o
.
bar
==
'twinkies!'
,
"call through proxy not passed through to original"
)
try
:
ref1
()
except
TypeError
:
# expect due to too few args
pass
else
:
raise
TestFailed
(
"did not catch expected TypeError -- too few args"
)
try
:
ref1
(
1
,
2
,
3
)
except
TypeError
:
# expect due to too many args
pass
else
:
raise
TestFailed
(
"did not catch expected TypeError -- too many args"
)
Lib/weakref.py
0 → 100644
Dosyayı görüntüle @
41deb1ef
"""Weak reference support for Python.
This module is an implementation of PEP 205:
http://python.sourceforge.net/peps/pep-0205.html
"""
import
UserDict
from
_weakref
import
\
getweakrefcount
,
\
getweakrefs
,
\
ref
,
\
proxy
,
\
ReferenceError
,
\
CallableProxyType
,
\
ProxyType
,
\
ReferenceType
ProxyTypes
=
(
ProxyType
,
CallableProxyType
)
def
mapping
(
dict
=
None
):
return
WeakDictionary
(
dict
)
class
WeakDictionary
(
UserDict
.
UserDict
):
# We inherit the constructor without worrying about the input
# dictionary; since it uses our .update() method, we get the right
# checks (if the other dictionary is a WeakDictionary, objects are
# unwrapped on the way out, and we always wrap on the way in).
def
__getitem__
(
self
,
key
):
o
=
self
.
data
.
get
(
key
)()
if
o
is
None
:
raise
KeyError
,
key
else
:
return
o
def
__repr__
(
self
):
return
"<WeakDictionary at
%
s>"
%
id
(
self
)
def
__setitem__
(
self
,
key
,
value
):
def
remove
(
o
,
data
=
self
.
data
,
key
=
key
):
del
data
[
key
]
self
.
data
[
key
]
=
ref
(
value
,
remove
)
def
copy
(
self
):
new
=
WeakDictionary
()
for
key
,
ref
in
self
.
data
.
items
():
o
=
ref
()
if
o
is
not
None
:
new
[
key
]
=
o
def
get
(
self
,
key
,
default
):
try
:
ref
=
self
.
data
[
key
]
except
KeyError
:
return
default
else
:
o
=
ref
()
if
o
is
None
:
# This should only happen
return
default
else
:
return
o
def
items
(
self
):
L
=
self
.
data
.
items
()
for
i
in
range
(
len
(
L
)):
key
,
ref
=
L
[
i
]
o
=
ref
()
if
o
is
not
None
:
L
[
i
]
=
key
,
o
return
L
def
popitem
(
self
):
while
1
:
key
,
ref
=
self
.
data
.
popitem
()
o
=
ref
()
if
o
is
not
None
:
return
key
,
o
def
setdefault
(
self
,
key
,
default
):
try
:
ref
=
self
.
data
[
key
]
except
KeyError
:
def
remove
(
o
,
data
=
self
.
data
,
key
=
key
):
del
data
[
key
]
ref
=
ref
(
default
,
remove
)
self
.
data
[
key
]
=
ref
return
default
else
:
return
ref
()
def
update
(
self
,
dict
):
d
=
self
.
data
L
=
[]
for
key
,
o
in
dict
.
items
():
def
remove
(
o
,
data
=
d
,
key
=
key
):
del
data
[
key
]
L
.
append
(
key
,
ref
(
o
,
remove
))
for
key
,
r
in
L
:
d
[
key
]
=
r
def
values
(
self
):
L
=
[]
for
ref
in
self
.
data
.
values
():
o
=
ref
()
if
o
is
not
None
:
L
.
append
(
o
)
return
L
# no longer needed
del
UserDict
Modules/_weakref.c
0 → 100644
Dosyayı görüntüle @
41deb1ef
This diff is collapsed.
Click to expand it.
Objects/classobject.c
Dosyayı görüntüle @
41deb1ef
...
...
@@ -515,6 +515,10 @@ instance_dealloc(register PyInstanceObject *inst)
#ifdef Py_REF_DEBUG
extern
long
_Py_RefTotal
;
#endif
if
(
!
PyObject_ClearWeakRefs
((
PyObject
*
)
inst
))
return
;
/* Temporarily resurrect the object. */
#ifdef Py_TRACE_REFS
#ifndef Py_REF_DEBUG
...
...
@@ -1771,6 +1775,7 @@ PyTypeObject PyInstance_Type = {
(
traverseproc
)
instance_traverse
,
/* tp_traverse */
0
,
/* tp_clear */
instance_richcompare
,
/* tp_richcompare */
offsetof
(
PyInstanceObject
,
in_weakreflist
)
/* tp_weaklistoffset */
};
...
...
Objects/object.c
Dosyayı görüntüle @
41deb1ef
...
...
@@ -100,6 +100,10 @@ PyObject_Init(PyObject *op, PyTypeObject *tp)
/* Any changes should be reflected in PyObject_INIT (objimpl.h) */
op
->
ob_type
=
tp
;
_Py_NewReference
(
op
);
if
(
PyType_SUPPORTS_WEAKREFS
(
tp
))
{
PyObject
**
weaklist
=
PyObject_GET_WEAKREFS_LISTPTR
(
op
);
*
weaklist
=
NULL
;
}
return
op
;
}
...
...
@@ -119,6 +123,10 @@ PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, int size)
op
->
ob_size
=
size
;
op
->
ob_type
=
tp
;
_Py_NewReference
((
PyObject
*
)
op
);
if
(
PyType_SUPPORTS_WEAKREFS
(
tp
))
{
PyObject
**
weaklist
=
PyObject_GET_WEAKREFS_LISTPTR
(
op
);
*
weaklist
=
NULL
;
}
return
op
;
}
...
...
@@ -1458,6 +1466,21 @@ PyObject_Free(void *p)
}
/* Hook to clear up weak references only once the _weakref module is
imported. We use a dummy implementation to simplify the code at each
call site instead of requiring a test for NULL.
*/
static
int
empty_clear_weak_refs
(
PyObject
*
o
)
{
return
1
;
}
int
(
*
PyObject_ClearWeakRefs
)(
PyObject
*
)
=
empty_clear_weak_refs
;
/* These methods are used to control infinite recursion in repr, str, print,
etc. Container objects that may recursively contain themselves,
e.g. builtin dictionaries and lists, should used Py_ReprEnter() and
...
...
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