• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Gallopsled / pwntools / 4c743a92f3eed7759ae5f16bdf9079e7854f0003

pending completion
4c743a92f3eed7759ae5f16bdf9079e7854f0003

push

github-actions

gogo
Fix testing.

3938 of 6504 branches covered (60.55%)

17 of 17 new or added lines in 1 file covered. (100.0%)

12343 of 16873 relevant lines covered (73.15%)

0.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.09
/pwnlib/atexit.py
1
"""
2
Replacement for the Python standard library's atexit.py.
3

4
Whereas the standard :mod:`atexit` module only defines :func:`atexit.register`,
5
this replacement module also defines :func:`unregister`.
6

7
This module also fixes a the issue that exceptions raised by an exit handler is
8
printed twice when the standard :mod:`atexit` is used.
9
"""
10
from __future__ import absolute_import
1✔
11
from __future__ import division
1✔
12

13
import sys
1✔
14
import threading
1✔
15
import traceback
1✔
16
import atexit as std_atexit
1✔
17

18
from pwnlib.context import context
1✔
19

20
__all__ = ['register', 'unregister']
1✔
21

22
_lock = threading.Lock()
1✔
23
_ident = 0
1✔
24
_handlers = {}
1✔
25

26
def register(func, *args, **kwargs):
1✔
27
    """register(func, *args, **kwargs)
28

29
    Registers a function to be called on program termination.  The function will
30
    be called with positional arguments `args` and keyword arguments `kwargs`,
31
    i.e. ``func(*args, **kwargs)``.  The current `context` is recorded and will
32
    be the one used when the handler is run.
33

34
    E.g. to suppress logging output from an exit-handler one could write::
35

36
      with context.local(log_level = 'error'):
37
        atexit.register(handler)
38

39
    An identifier is returned which can be used to unregister the exit-handler.
40

41
    This function can be used as a decorator::
42

43
      @atexit.register
44
      def handler():
45
        ...
46

47
    Notice however that this will bind ``handler`` to the identifier and not the
48
    actual exit-handler.  The exit-handler can then be unregistered with::
49

50
      atexit.unregister(handler)
51

52
    This function is thread safe.
53

54
    """
55
    global _ident
56
    with _lock:
1✔
57
        ident = _ident
1✔
58
        _ident += 1
1✔
59
    _handlers[ident] = (func, args, kwargs, vars(context))
1✔
60
    return ident
1✔
61

62
def unregister(ident):
1✔
63
    """unregister(ident)
64

65
    Remove the exit-handler identified by `ident` from the list of registered
66
    handlers.  If `ident` isn't registered this is a no-op.
67
    """
68
    if ident in _handlers:
×
69
        del _handlers[ident]
×
70

71
def _run_handlers():
1✔
72
    """_run_handlers()
73

74
    Run registered exit-handlers.  They run in the reverse order of which they
75
    were registered.
76

77
    If a handler raises an exception, it will be printed but nothing else
78
    happens, i.e. other handlers will be run and `sys.excepthook` will not be
79
    called for that reason.
80
    """
81
    context.clear()
1✔
82
    for _ident, (func, args, kwargs, ctx) in \
1!
83
        sorted(_handlers.items(), reverse = True):
84
        try:
1✔
85
            with context.local(**ctx):
1✔
86
                func(*args, **kwargs)
1✔
87
        except SystemExit:
×
88
            pass
×
89
        except Exception:
×
90
            # extract the current exception and rewind the traceback to where it
91
            # originated
92
            typ, val, tb = sys.exc_info()
×
93
            traceback.print_exception(typ, val, tb.tb_next)
×
94

95
# if there's already an exitfunc registered be sure to run that too
96
if hasattr(sys, "exitfunc"):
1!
97
    register(sys.exitfunc)
1✔
98

99
if sys.version_info[0] < 3:
1!
100
    sys.exitfunc = _run_handlers
1✔
101
else:
102
    std_atexit.register(_run_handlers)
×
103

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc