-
Notifications
You must be signed in to change notification settings - Fork 222
Initial version of auto-detection of terminal width. #110
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
base: master
Are you sure you want to change the base?
Changes from 5 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 shutil | ||
| import sys | ||
| from datetime import datetime | ||
| from contextlib import contextmanager | ||
|
|
@@ -154,15 +155,38 @@ def format_pair(prefix, arg, value): | |
| return '\n'.join(lines) | ||
|
|
||
|
|
||
| def argumentToString(obj): | ||
| s = DEFAULT_ARG_TO_STRING_FUNCTION(obj) | ||
| 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 detect_terminal_width(prefix, default=DEFAULT_LINE_WRAP_WIDTH): | ||
| """ Returns the number of columns that this terminal can handle. """ | ||
| width = default | ||
| try: | ||
| if hasattr(shutil, "get_terminal_size"): | ||
| width = shutil.get_terminal_size().columns | ||
| else: # Python 2.x doesn't support get_terminal_size | ||
| from backports.shutil_get_terminal_size import get_terminal_size | ||
| width = get_terminal_size().columns | ||
| except OSError: # Not in TTY | ||
|
Collaborator
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
Author
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 | ||
| return width - len(prefix) | ||
|
|
||
|
|
||
| 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 | ||
| contextDelimiter = DEFAULT_CONTEXT_DELIMITER | ||
|
|
||
| def __init__(self, prefix=DEFAULT_PREFIX, | ||
|
|
@@ -173,6 +197,8 @@ def __init__(self, prefix=DEFAULT_PREFIX, | |
| self.includeContext = includeContext | ||
| self.outputFunction = outputFunction | ||
| self.argToStringFunction = argToStringFunction | ||
| self.passWidthParam = supports_param(self.argToStringFunction) | ||
| self.lineWrapWidth = detect_terminal_width(self.prefix, DEFAULT_LINE_WRAP_WIDTH) | ||
|
Collaborator
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 still doesn't account for the width of
Author
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. Good point, will fix. |
||
|
|
||
| def __call__(self, *args): | ||
| if self.enabled: | ||
|
|
@@ -232,7 +258,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 +352,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.
I'd prefer to have near the top of the file:
icecream should still work if
backports.shutil_get_terminal_sizeisn't installed, e.g. if the user chooses to uninstall it even after installing it automatically.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.
Will do it that way then 👍
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.
(Although in my terminal,
env['COLUMNS']isn't set, so I'm not sure which environments/OSes do set that variable)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.
I don't know anything about this either, but I imagine it's a convention so that humans can easily set COLUMNS=50 when running a program and expect that many parts of the program will automatically respect that.