console.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. """
  2. Internal module for console introspection
  3. """
  4. import locale
  5. import sys
  6. from pandas.io.formats.terminal import get_terminal_size
  7. # -----------------------------------------------------------------------------
  8. # Global formatting options
  9. _initial_defencoding = None
  10. def detect_console_encoding():
  11. """
  12. Try to find the most capable encoding supported by the console.
  13. slightly modified from the way IPython handles the same issue.
  14. """
  15. global _initial_defencoding
  16. encoding = None
  17. try:
  18. encoding = sys.stdout.encoding or sys.stdin.encoding
  19. except (AttributeError, IOError):
  20. pass
  21. # try again for something better
  22. if not encoding or 'ascii' in encoding.lower():
  23. try:
  24. encoding = locale.getpreferredencoding()
  25. except Exception:
  26. pass
  27. # when all else fails. this will usually be "ascii"
  28. if not encoding or 'ascii' in encoding.lower():
  29. encoding = sys.getdefaultencoding()
  30. # GH3360, save the reported defencoding at import time
  31. # MPL backends may change it. Make available for debugging.
  32. if not _initial_defencoding:
  33. _initial_defencoding = sys.getdefaultencoding()
  34. return encoding
  35. def get_console_size():
  36. """Return console size as tuple = (width, height).
  37. Returns (None,None) in non-interactive session.
  38. """
  39. from pandas import get_option
  40. display_width = get_option('display.width')
  41. # deprecated.
  42. display_height = get_option('display.max_rows')
  43. # Consider
  44. # interactive shell terminal, can detect term size
  45. # interactive non-shell terminal (ipnb/ipqtconsole), cannot detect term
  46. # size non-interactive script, should disregard term size
  47. # in addition
  48. # width,height have default values, but setting to 'None' signals
  49. # should use Auto-Detection, But only in interactive shell-terminal.
  50. # Simple. yeah.
  51. if in_interactive_session():
  52. if in_ipython_frontend():
  53. # sane defaults for interactive non-shell terminal
  54. # match default for width,height in config_init
  55. from pandas.core.config import get_default_val
  56. terminal_width = get_default_val('display.width')
  57. terminal_height = get_default_val('display.max_rows')
  58. else:
  59. # pure terminal
  60. terminal_width, terminal_height = get_terminal_size()
  61. else:
  62. terminal_width, terminal_height = None, None
  63. # Note if the User sets width/Height to None (auto-detection)
  64. # and we're in a script (non-inter), this will return (None,None)
  65. # caller needs to deal.
  66. return (display_width or terminal_width, display_height or terminal_height)
  67. # ----------------------------------------------------------------------
  68. # Detect our environment
  69. def in_interactive_session():
  70. """ check if we're running in an interactive shell
  71. returns True if running under python/ipython interactive shell
  72. """
  73. from pandas import get_option
  74. def check_main():
  75. try:
  76. import __main__ as main
  77. except ModuleNotFoundError:
  78. return get_option('mode.sim_interactive')
  79. return (not hasattr(main, '__file__') or
  80. get_option('mode.sim_interactive'))
  81. try:
  82. return __IPYTHON__ or check_main() # noqa
  83. except NameError:
  84. return check_main()
  85. def in_qtconsole():
  86. """
  87. check if we're inside an IPython qtconsole
  88. .. deprecated:: 0.14.1
  89. This is no longer needed, or working, in IPython 3 and above.
  90. """
  91. try:
  92. ip = get_ipython() # noqa
  93. front_end = (
  94. ip.config.get('KernelApp', {}).get('parent_appname', "") or
  95. ip.config.get('IPKernelApp', {}).get('parent_appname', ""))
  96. if 'qtconsole' in front_end.lower():
  97. return True
  98. except NameError:
  99. return False
  100. return False
  101. def in_ipnb():
  102. """
  103. check if we're inside an IPython Notebook
  104. .. deprecated:: 0.14.1
  105. This is no longer needed, or working, in IPython 3 and above.
  106. """
  107. try:
  108. ip = get_ipython() # noqa
  109. front_end = (
  110. ip.config.get('KernelApp', {}).get('parent_appname', "") or
  111. ip.config.get('IPKernelApp', {}).get('parent_appname', ""))
  112. if 'notebook' in front_end.lower():
  113. return True
  114. except NameError:
  115. return False
  116. return False
  117. def in_ipython_frontend():
  118. """
  119. check if we're inside an an IPython zmq frontend
  120. """
  121. try:
  122. ip = get_ipython() # noqa
  123. return 'zmq' in str(type(ip)).lower()
  124. except NameError:
  125. pass
  126. return False