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