Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
gmsh
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Romin Tomasetti
gmsh
Commits
e17ac718
Commit
e17ac718
authored
7 years ago
by
Jonathan Lambrechts
Browse files
Options
Downloads
Patches
Plain Diff
api python bindings : add backports.weakref
parent
5aefd45c
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
api/backports/__init__.py
+4
-0
4 additions, 0 deletions
api/backports/__init__.py
api/backports/weakref.py
+151
-0
151 additions, 0 deletions
api/backports/weakref.py
with
155 additions
and
0 deletions
api/backports/__init__.py
0 → 100644
+
4
−
0
View file @
e17ac718
# See https://pypi.python.org/pypi/backports
from
pkgutil
import
extend_path
__path__
=
extend_path
(
__path__
,
__name__
)
This diff is collapsed.
Click to expand it.
api/backports/weakref.py
0 → 100644
+
151
−
0
View file @
e17ac718
"""
Partial backport of Python 3.6
'
s weakref module:
finalize (new in Python 3.4)
Backport modifications are marked with
"
XXX backport
"
.
"""
from
__future__
import
absolute_import
import
itertools
import
sys
from
weakref
import
ref
__all__
=
[
'
finalize
'
]
class
finalize
(
object
):
"""
Class for finalization of weakrefable objects
finalize(obj, func, *args, **kwargs) returns a callable finalizer
object which will be called when obj is garbage collected. The
first time the finalizer is called it evaluates func(*arg, **kwargs)
and returns the result. After this the finalizer is dead, and
calling it just returns None.
When the program exits any remaining finalizers for which the
atexit attribute is true will be run in reverse order of creation.
By default atexit is true.
"""
# Finalizer objects don't have any state of their own. They are
# just used as keys to lookup _Info objects in the registry. This
# ensures that they cannot be part of a ref-cycle.
__slots__
=
()
_registry
=
{}
_shutdown
=
False
_index_iter
=
itertools
.
count
()
_dirty
=
False
_registered_with_atexit
=
False
class
_Info
(
object
):
__slots__
=
(
"
weakref
"
,
"
func
"
,
"
args
"
,
"
kwargs
"
,
"
atexit
"
,
"
index
"
)
def
__init__
(
self
,
obj
,
func
,
*
args
,
**
kwargs
):
if
not
self
.
_registered_with_atexit
:
# We may register the exit function more than once because
# of a thread race, but that is harmless
import
atexit
atexit
.
register
(
self
.
_exitfunc
)
finalize
.
_registered_with_atexit
=
True
info
=
self
.
_Info
()
info
.
weakref
=
ref
(
obj
,
self
)
info
.
func
=
func
info
.
args
=
args
info
.
kwargs
=
kwargs
or
None
info
.
atexit
=
True
info
.
index
=
next
(
self
.
_index_iter
)
self
.
_registry
[
self
]
=
info
finalize
.
_dirty
=
True
def
__call__
(
self
,
_
=
None
):
"""
If alive then mark as dead and return func(*args, **kwargs);
otherwise return None
"""
info
=
self
.
_registry
.
pop
(
self
,
None
)
if
info
and
not
self
.
_shutdown
:
return
info
.
func
(
*
info
.
args
,
**
(
info
.
kwargs
or
{}))
def
detach
(
self
):
"""
If alive then mark as dead and return (obj, func, args, kwargs);
otherwise return None
"""
info
=
self
.
_registry
.
get
(
self
)
obj
=
info
and
info
.
weakref
()
if
obj
is
not
None
and
self
.
_registry
.
pop
(
self
,
None
):
return
(
obj
,
info
.
func
,
info
.
args
,
info
.
kwargs
or
{})
def
peek
(
self
):
"""
If alive then return (obj, func, args, kwargs);
otherwise return None
"""
info
=
self
.
_registry
.
get
(
self
)
obj
=
info
and
info
.
weakref
()
if
obj
is
not
None
:
return
(
obj
,
info
.
func
,
info
.
args
,
info
.
kwargs
or
{})
@property
def
alive
(
self
):
"""
Whether finalizer is alive
"""
return
self
in
self
.
_registry
@property
def
atexit
(
self
):
"""
Whether finalizer should be called at exit
"""
info
=
self
.
_registry
.
get
(
self
)
return
bool
(
info
)
and
info
.
atexit
@atexit.setter
def
atexit
(
self
,
value
):
info
=
self
.
_registry
.
get
(
self
)
if
info
:
info
.
atexit
=
bool
(
value
)
def
__repr__
(
self
):
info
=
self
.
_registry
.
get
(
self
)
obj
=
info
and
info
.
weakref
()
if
obj
is
None
:
return
'
<%s object at %#x; dead>
'
%
(
type
(
self
).
__name__
,
id
(
self
))
else
:
return
'
<%s object at %#x; for %r at %#x>
'
%
\
(
type
(
self
).
__name__
,
id
(
self
),
type
(
obj
).
__name__
,
id
(
obj
))
@classmethod
def
_select_for_exit
(
cls
):
# Return live finalizers marked for exit, oldest first
L
=
[(
f
,
i
)
for
(
f
,
i
)
in
cls
.
_registry
.
items
()
if
i
.
atexit
]
L
.
sort
(
key
=
lambda
item
:
item
[
1
].
index
)
return
[
f
for
(
f
,
i
)
in
L
]
@classmethod
def
_exitfunc
(
cls
):
# At shutdown invoke finalizers for which atexit is true.
# This is called once all other non-daemonic threads have been
# joined.
reenable_gc
=
False
try
:
if
cls
.
_registry
:
import
gc
if
gc
.
isenabled
():
reenable_gc
=
True
gc
.
disable
()
pending
=
None
while
True
:
if
pending
is
None
or
finalize
.
_dirty
:
pending
=
cls
.
_select_for_exit
()
finalize
.
_dirty
=
False
if
not
pending
:
break
f
=
pending
.
pop
()
try
:
# gc is disabled, so (assuming no daemonic
# threads) the following is the only line in
# this function which might trigger creation
# of a new finalizer
f
()
except
Exception
:
sys
.
excepthook
(
*
sys
.
exc_info
())
assert
f
not
in
cls
.
_registry
finally
:
# prevent any more finalizers from executing during shutdown
finalize
.
_shutdown
=
True
if
reenable_gc
:
gc
.
enable
()
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment