-
Notifications
You must be signed in to change notification settings - Fork 197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial version of auto-detection of terminal width. #110
base: master
Are you sure you want to change the base?
Changes from 3 commits
e191743
42f96c7
7e3256b
d47c5f7
8f3658f
e26249f
661e58e
78b0ae9
c10907d
2236996
9490fa3
4a8ab87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ | |
import ast | ||
import inspect | ||
import pprint | ||
import os | ||
import sys | ||
from datetime import datetime | ||
from contextlib import contextmanager | ||
|
@@ -87,6 +88,7 @@ def colorizedStderrPrint(s): | |
DEFAULT_CONTEXT_DELIMITER = '- ' | ||
DEFAULT_OUTPUT_FUNCTION = colorizedStderrPrint | ||
DEFAULT_ARG_TO_STRING_FUNCTION = pprint.pformat | ||
COLUMN_OVERFLOW = 4 # Line length appears to overflow by 4 characters. | ||
|
||
|
||
class NoSourceAvailableError(OSError): | ||
|
@@ -154,15 +156,40 @@ def format_pair(prefix, arg, value): | |
return '\n'.join(lines) | ||
|
||
|
||
def argumentToString(obj): | ||
s = DEFAULT_ARG_TO_STRING_FUNCTION(obj) | ||
# def argumentToString(obj, width): | ||
def argumentToString(obj, width=DEFAULT_LINE_WRAP_WIDTH): | ||
s = DEFAULT_ARG_TO_STRING_FUNCTION(obj, width=width) | ||
s = s.replace('\\n', '\n') # Preserve string newlines in output. | ||
return s | ||
|
||
|
||
def columns(): | ||
""" Returns the number of columns that this terminal can handle. """ | ||
width = DEFAULT_LINE_WRAP_WIDTH | ||
try: | ||
# TODO come up with a more elegant solution than subtracting | ||
# a seemingly random number of characters. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any thoughts about this overflow thingy? I just realised that the extra characters might come from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's probably what it is, yes. Have this function return the full width, then deal with the length of the prefix inside the class. Remember there's both the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me know what you think of my new solution. |
||
width = os.get_terminal_size().columns - COLUMN_OVERFLOW | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The docs https://docs.python.org/3/library/os.html#os.get_terminal_size suggest using shutil (https://docs.python.org/3/library/shutil.html#shutil.get_terminal_size) instead, and looking at that function I think that's a good idea. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
except OSError: # Not in TTY | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like the shutil version doesn't raise OSError any more. But maybe the whole thing should be wrapped in Also you should pass the default width as a fallback to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do on both counts. |
||
pass | ||
except AttributeError: # Python 2.x | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks a bit too broad and prone to hiding real errors. I'd prefer either checking the Python version or checking for the presence of the relevant attribute. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
width = os.environ.get('COLUMNS', DEFAULT_LINE_WRAP_WIDTH) | ||
return width | ||
|
||
|
||
def supports_param(fn, param="width"): | ||
""" Returns True if the function supports that parameter. """ | ||
try: | ||
from inspect import signature | ||
return param in signature(fn).parameters | ||
except ImportError: # Python 2.x | ||
from inspect import getargspec | ||
return param in getargspec(fn).args | ||
|
||
|
||
class IceCreamDebugger: | ||
_pairDelimiter = ', ' # Used by the tests in tests/. | ||
lineWrapWidth = DEFAULT_LINE_WRAP_WIDTH | ||
lineWrapWidth = columns() | ||
contextDelimiter = DEFAULT_CONTEXT_DELIMITER | ||
|
||
def __init__(self, prefix=DEFAULT_PREFIX, | ||
|
@@ -173,6 +200,7 @@ def __init__(self, prefix=DEFAULT_PREFIX, | |
self.includeContext = includeContext | ||
self.outputFunction = outputFunction | ||
self.argToStringFunction = argToStringFunction | ||
self.passWidthParam = supports_param(self.argToStringFunction) | ||
|
||
def __call__(self, *args): | ||
if self.enabled: | ||
|
@@ -232,7 +260,8 @@ def _constructArgumentOutput(self, prefix, context, pairs): | |
def argPrefix(arg): | ||
return '%s: ' % arg | ||
|
||
pairs = [(arg, self.argToStringFunction(val)) for arg, val in pairs] | ||
kwargs = {"width": self.lineWrapWidth} if self.passWidthParam else {} | ||
pairs = [(arg, self.argToStringFunction(val, **kwargs)) for arg, val in pairs] | ||
# For cleaner output, if <arg> is a literal, eg 3, "string", b'bytes', | ||
# etc, only output the value, not the argument and the value, as the | ||
# argument and the value will be identical or nigh identical. Ex: with | ||
|
@@ -325,6 +354,7 @@ def configureOutput(self, prefix=_absent, outputFunction=_absent, | |
|
||
if argToStringFunction is not _absent: | ||
self.argToStringFunction = argToStringFunction | ||
self.passWidthParam = supports_param(self.argToStringFunction) | ||
|
||
if includeContext is not _absent: | ||
self.includeContext = includeContext | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please give this a more descriptive name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.