Files
PySnooper/pysnooper/utils.py
2019-07-17 09:32:19 +03:00

89 lines
1.9 KiB
Python

# Copyright 2019 Ram Rachum and collaborators.
# This program is distributed under the MIT license.
import abc
import sys
from .pycompat import ABC, string_types, collections_abc
MAX_VARIABLE_LENGTH = 100
MAX_EXCEPTION_LENGTH = 200
def _check_methods(C, *methods):
mro = C.__mro__
for method in methods:
for B in mro:
if method in B.__dict__:
if B.__dict__[method] is None:
return NotImplemented
break
else:
return NotImplemented
return True
class WritableStream(ABC):
@abc.abstractmethod
def write(self, s):
pass
@classmethod
def __subclasshook__(cls, C):
if cls is WritableStream:
return _check_methods(C, 'write')
return NotImplemented
file_reading_errors = (
IOError,
OSError,
ValueError # IronPython weirdness.
)
def shitcode(s):
return ''.join(
(c if (0 < ord(c) < 256) else '?') for c in s
)
def get_repr_function(item, custom_repr):
for condition, action in custom_repr:
if isinstance(condition, type):
condition = lambda x, y=condition: isinstance(x, y)
if condition(item):
return action
return repr
def get_shortish_repr(item, custom_repr=()):
repr_function = get_repr_function(item, custom_repr)
try:
r = repr_function(item)
except Exception:
r = 'REPR FAILED'
r = r.replace('\r', '').replace('\n', '')
r = truncate(r, MAX_VARIABLE_LENGTH)
return r
def truncate(string, max_length):
if len(string) > max_length:
left = (max_length - 3) // 2
right = max_length - 3 - left
string = u'{}...{}'.format(string[:left], string[-right:])
return string
def ensure_tuple(x):
if isinstance(x, collections_abc.Iterable) and \
not isinstance(x, string_types):
return tuple(x)
else:
return (x,)