1"""
2Internal module for console introspection
3"""
4from __future__ import annotations
5
6from shutil import get_terminal_size
7
8
9def get_console_size() -> tuple[int | None, int | None]:
10 """
11 Return console size as tuple = (width, height).
12
13 Returns (None,None) in non-interactive session.
14 """
15 from pandas import get_option
16
17 display_width = get_option("display.width")
18 display_height = get_option("display.max_rows")
19
20 # Consider
21 # interactive shell terminal, can detect term size
22 # interactive non-shell terminal (ipnb/ipqtconsole), cannot detect term
23 # size non-interactive script, should disregard term size
24
25 # in addition
26 # width,height have default values, but setting to 'None' signals
27 # should use Auto-Detection, But only in interactive shell-terminal.
28 # Simple. yeah.
29
30 if in_interactive_session():
31 if in_ipython_frontend():
32 # sane defaults for interactive non-shell terminal
33 # match default for width,height in config_init
34 from pandas._config.config import get_default_val
35
36 terminal_width = get_default_val("display.width")
37 terminal_height = get_default_val("display.max_rows")
38 else:
39 # pure terminal
40 terminal_width, terminal_height = get_terminal_size()
41 else:
42 terminal_width, terminal_height = None, None
43
44 # Note if the User sets width/Height to None (auto-detection)
45 # and we're in a script (non-inter), this will return (None,None)
46 # caller needs to deal.
47 return display_width or terminal_width, display_height or terminal_height
48
49
50# ----------------------------------------------------------------------
51# Detect our environment
52
53
54def in_interactive_session() -> bool:
55 """
56 Check if we're running in an interactive shell.
57
58 Returns
59 -------
60 bool
61 True if running under python/ipython interactive shell.
62 """
63 from pandas import get_option
64
65 def check_main():
66 try:
67 import __main__ as main
68 except ModuleNotFoundError:
69 return get_option("mode.sim_interactive")
70 return not hasattr(main, "__file__") or get_option("mode.sim_interactive")
71
72 try:
73 # error: Name '__IPYTHON__' is not defined
74 return __IPYTHON__ or check_main() # type: ignore[name-defined]
75 except NameError:
76 return check_main()
77
78
79def in_ipython_frontend() -> bool:
80 """
81 Check if we're inside an IPython zmq frontend.
82
83 Returns
84 -------
85 bool
86 """
87 try:
88 # error: Name 'get_ipython' is not defined
89 ip = get_ipython() # type: ignore[name-defined]
90 return "zmq" in str(type(ip)).lower()
91 except NameError:
92 pass
93
94 return False