Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
e6410c53
Commit
e6410c53
authored
Mar 29, 2010
by
Michael Foord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Backport of weakref.WeakSet and tests from Python 3.
parent
b8d688cd
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
602 additions
and
1 deletion
+602
-1
Doc/library/weakref.rst
Doc/library/weakref.rst
+8
-0
Lib/_weakrefset.py
Lib/_weakrefset.py
+212
-0
Lib/test/test_weakset.py
Lib/test/test_weakset.py
+376
-0
Lib/unittest/test/test_result.py
Lib/unittest/test/test_result.py
+1
-0
Lib/weakref.py
Lib/weakref.py
+3
-1
Misc/NEWS
Misc/NEWS
+2
-0
No files found.
Doc/library/weakref.rst
View file @
e6410c53
...
...
@@ -209,6 +209,14 @@ methods of :class:`WeakKeyDictionary` objects.
.. versionadded:: 2.5
.. class:: WeakSet([elements])
Set class that keeps weak references to its elements. An element will be
discarded when no strong reference to it exists any more.
.. versionadded:: 2.7
.. data:: ReferenceType
The type object for weak references objects.
...
...
Lib/_weakrefset.py
0 → 100644
View file @
e6410c53
# Access WeakSet through the weakref module.
# This code is separated-out because it is needed
# by abc.py to load everything else at startup.
from
_weakref
import
ref
__all__
=
[
'WeakSet'
]
class
_IterationGuard
(
object
):
# This context manager registers itself in the current iterators of the
# weak container, such as to delay all removals until the context manager
# exits.
# This technique should be relatively thread-safe (since sets are).
def
__init__
(
self
,
weakcontainer
):
# Don't create cycles
self
.
weakcontainer
=
ref
(
weakcontainer
)
def
__enter__
(
self
):
w
=
self
.
weakcontainer
()
if
w
is
not
None
:
w
.
_iterating
.
add
(
self
)
return
self
def
__exit__
(
self
,
e
,
t
,
b
):
w
=
self
.
weakcontainer
()
if
w
is
not
None
:
s
=
w
.
_iterating
s
.
remove
(
self
)
if
not
s
:
w
.
_commit_removals
()
class
WeakSet
(
object
):
def
__init__
(
self
,
data
=
None
):
self
.
data
=
set
()
def
_remove
(
item
,
selfref
=
ref
(
self
)):
self
=
selfref
()
if
self
is
not
None
:
if
self
.
_iterating
:
self
.
_pending_removals
.
append
(
item
)
else
:
self
.
data
.
discard
(
item
)
self
.
_remove
=
_remove
# A list of keys to be removed
self
.
_pending_removals
=
[]
self
.
_iterating
=
set
()
if
data
is
not
None
:
self
.
update
(
data
)
def
_commit_removals
(
self
):
l
=
self
.
_pending_removals
discard
=
self
.
data
.
discard
while
l
:
discard
(
l
.
pop
())
def
__iter__
(
self
):
with
_IterationGuard
(
self
):
for
itemref
in
self
.
data
:
item
=
itemref
()
if
item
is
not
None
:
yield
item
def
__len__
(
self
):
return
sum
(
x
()
is
not
None
for
x
in
self
.
data
)
def
__contains__
(
self
,
item
):
return
ref
(
item
)
in
self
.
data
def
__reduce__
(
self
):
return
(
self
.
__class__
,
(
list
(
self
),),
getattr
(
self
,
'__dict__'
,
None
))
__hash__
=
None
def
add
(
self
,
item
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
self
.
data
.
add
(
ref
(
item
,
self
.
_remove
))
def
clear
(
self
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
self
.
data
.
clear
()
def
copy
(
self
):
return
self
.
__class__
(
self
)
def
pop
(
self
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
while
True
:
try
:
itemref
=
self
.
data
.
pop
()
except
KeyError
:
raise
KeyError
(
'pop from empty WeakSet'
)
item
=
itemref
()
if
item
is
not
None
:
return
item
def
remove
(
self
,
item
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
self
.
data
.
remove
(
ref
(
item
))
def
discard
(
self
,
item
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
self
.
data
.
discard
(
ref
(
item
))
def
update
(
self
,
other
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
if
isinstance
(
other
,
self
.
__class__
):
self
.
data
.
update
(
other
.
data
)
else
:
for
element
in
other
:
self
.
add
(
element
)
def
__ior__
(
self
,
other
):
self
.
update
(
other
)
return
self
# Helper functions for simple delegating methods.
def
_apply
(
self
,
other
,
method
):
if
not
isinstance
(
other
,
self
.
__class__
):
other
=
self
.
__class__
(
other
)
newdata
=
method
(
other
.
data
)
newset
=
self
.
__class__
()
newset
.
data
=
newdata
return
newset
def
difference
(
self
,
other
):
return
self
.
_apply
(
other
,
self
.
data
.
difference
)
__sub__
=
difference
def
difference_update
(
self
,
other
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
if
self
is
other
:
self
.
data
.
clear
()
else
:
self
.
data
.
difference_update
(
ref
(
item
)
for
item
in
other
)
def
__isub__
(
self
,
other
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
if
self
is
other
:
self
.
data
.
clear
()
else
:
self
.
data
.
difference_update
(
ref
(
item
)
for
item
in
other
)
return
self
def
intersection
(
self
,
other
):
return
self
.
_apply
(
other
,
self
.
data
.
intersection
)
__and__
=
intersection
def
intersection_update
(
self
,
other
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
self
.
data
.
intersection_update
(
ref
(
item
)
for
item
in
other
)
def
__iand__
(
self
,
other
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
self
.
data
.
intersection_update
(
ref
(
item
)
for
item
in
other
)
return
self
def
issubset
(
self
,
other
):
return
self
.
data
.
issubset
(
ref
(
item
)
for
item
in
other
)
__lt__
=
issubset
def
__le__
(
self
,
other
):
return
self
.
data
<=
set
(
ref
(
item
)
for
item
in
other
)
def
issuperset
(
self
,
other
):
return
self
.
data
.
issuperset
(
ref
(
item
)
for
item
in
other
)
__gt__
=
issuperset
def
__ge__
(
self
,
other
):
return
self
.
data
>=
set
(
ref
(
item
)
for
item
in
other
)
def
__eq__
(
self
,
other
):
if
not
isinstance
(
other
,
self
.
__class__
):
return
NotImplemented
return
self
.
data
==
set
(
ref
(
item
)
for
item
in
other
)
def
symmetric_difference
(
self
,
other
):
return
self
.
_apply
(
other
,
self
.
data
.
symmetric_difference
)
__xor__
=
symmetric_difference
def
symmetric_difference_update
(
self
,
other
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
if
self
is
other
:
self
.
data
.
clear
()
else
:
self
.
data
.
symmetric_difference_update
(
ref
(
item
)
for
item
in
other
)
def
__ixor__
(
self
,
other
):
if
self
.
_pending_removals
:
self
.
_commit_removals
()
if
self
is
other
:
self
.
data
.
clear
()
else
:
self
.
data
.
symmetric_difference_update
(
ref
(
item
)
for
item
in
other
)
return
self
def
union
(
self
,
other
):
return
self
.
_apply
(
other
,
self
.
data
.
union
)
__or__
=
union
def
isdisjoint
(
self
,
other
):
return
len
(
self
.
intersection
(
other
))
==
0
Lib/test/test_weakset.py
0 → 100644
View file @
e6410c53
This diff is collapsed.
Click to expand it.
Lib/unittest/test/test_result.py
View file @
e6410c53
...
...
@@ -24,6 +24,7 @@ class Test_TestResult(unittest.TestCase):
self
.
assertEqual
(
result
.
testsRun
,
0
)
self
.
assertEqual
(
result
.
shouldStop
,
False
)
# "This method can be called to signal that the set of tests being
# run should be aborted by setting the TestResult's shouldStop
# attribute to True."
...
...
Lib/weakref.py
View file @
e6410c53
...
...
@@ -20,6 +20,8 @@ from _weakref import (
ProxyType
,
ReferenceType
)
from
_weakrefset
import
WeakSet
from
exceptions
import
ReferenceError
...
...
@@ -27,7 +29,7 @@ ProxyTypes = (ProxyType, CallableProxyType)
__all__
=
[
"ref"
,
"proxy"
,
"getweakrefcount"
,
"getweakrefs"
,
"WeakKeyDictionary"
,
"ReferenceError"
,
"ReferenceType"
,
"ProxyType"
,
"CallableProxyType"
,
"ProxyTypes"
,
"WeakValueDictionary"
]
"CallableProxyType"
,
"ProxyTypes"
,
"WeakValueDictionary"
,
'WeakSet'
]
class
WeakValueDictionary
(
UserDict
.
UserDict
):
...
...
Misc/NEWS
View file @
e6410c53
...
...
@@ -37,6 +37,8 @@ Library
True/False. This makes Fraction <=> complex comparisons consistent with
int <=> complex, float <=> complex, and complex <=> complex comparisons.
- Addition of ``WeakSet`` to the ``weakref`` module.
- logging: Added LOG_FTP to SysLogHandler and updated documentation.
- Issue #8205: Remove the "Modules" directory from sys.path when Python is
...
...
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