/usr/lib/python3/dist-packages/duecredit/utils.py is in python3-duecredit 0.4.5.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | # emacs: -*- mode: python; py-indent-offset: 4; tab-width: 4; indent-tabs-mode: nil -*-
# ex: set sts=4 ts=4 sw=4 noet:
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
# See COPYING file distributed along with the duecredit package for the
# copyright and license terms. Originates from datalad package distributed
# under MIT license
#
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
import os
import logging
import sys
from functools import wraps
lgr = logging.getLogger("duecredit.utils")
#
# Little helpers
#
def is_interactive():
"""Return True if all in/outs are tty"""
if any(not hasattr(inout, 'isatty') for inout in (sys.stdin, sys.stdout, sys.stderr)):
lgr.warning("Assuming non interactive session since isatty found missing")
return False
# TODO: check on windows if hasattr check would work correctly and add value:
#
return sys.stdin.isatty() and sys.stdout.isatty() and sys.stderr.isatty()
#
# Decorators
#
# Borrowed from pandas
# Copyright: 2011-2014, Lambda Foundry, Inc. and PyData Development Team
# Licese: BSD-3
def optional_args(decorator):
"""allows a decorator to take optional positional and keyword arguments.
Assumes that taking a single, callable, positional argument means that
it is decorating a function, i.e. something like this::
@my_decorator
def function(): pass
Calls decorator with decorator(f, *args, **kwargs)"""
@wraps(decorator)
def wrapper(*args, **kwargs):
def dec(f):
return decorator(f, *args, **kwargs)
is_decorating = not kwargs and len(args) == 1 and callable(args[0])
if is_decorating:
f = args[0]
args = []
return dec(f)
else:
return dec
return wrapper
def never_fail(f):
"""Assure that function never fails -- all exceptions are caught"""
@wraps(f)
def wrapped_func(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception as e:
lgr.warning("DueCredit internal failure while running %s: %r. "
"Please report to developers at https://github.com/duecredit/duecredit/issues"
% (f, e))
if os.environ.get('DUECREDIT_ALLOW_FAIL', False):
return f
else:
return wrapped_func
def borrowdoc(cls, methodname=None, replace=None):
"""Return a decorator to borrow docstring from another `cls`.`methodname`
Common use is to borrow a docstring from the class's method for an
adapter function (e.g. sphere_searchlight borrows from Searchlight)
Examples
--------
To borrow `__repr__` docstring from parent class `Mapper`, do::
@borrowdoc(Mapper)
def __repr__(self):
...
Parameters
----------
cls
Usually a parent class
methodname : None or str
Name of the method from which to borrow. If None, would use
the same name as of the decorated method
replace : None or str, optional
If not None, then not entire docstring gets replaced but only the
matching to "replace" value string
"""
def _borrowdoc(method):
"""Decorator which assigns to the `method` docstring from another
"""
if methodname is None:
other_method = getattr(cls, method.__name__)
else:
other_method = getattr(cls, methodname)
if hasattr(other_method, '__doc__'):
if not replace:
method.__doc__ = other_method.__doc__
else:
method.__doc__ = method.__doc__.replace(replace, other_method.__doc__)
return method
return _borrowdoc
#
# Context Managers
#
#
# Additional handlers
#
_sys_excepthook = sys.excepthook # Just in case we ever need original one
def setup_exceptionhook():
"""Overloads default sys.excepthook with our exceptionhook handler.
If interactive, our exceptionhook handler will invoke
pdb.post_mortem; if not interactive, then invokes default handler.
"""
def _duecredit_pdb_excepthook(type, value, tb):
if is_interactive():
import traceback, pdb
traceback.print_exception(type, value, tb)
print
pdb.post_mortem(tb)
else:
lgr.warn("We cannot setup exception hook since not in interactive mode")
# we are in interactive mode or we don't have a tty-like
# device, so we call the default hook
#sys.__excepthook__(type, value, tb)
_sys_excepthook(type, value, tb)
sys.excepthook = _duecredit_pdb_excepthook
|