6565)
6666
6767import rich .box
68- from rich .console import Group , RenderableType
68+ from rich .console import (
69+ Console ,
70+ Group ,
71+ RenderableType ,
72+ )
6973from rich .highlighter import ReprHighlighter
7074from rich .rule import Rule
7175from rich .style import Style , StyleType
133137 shlex_split ,
134138)
135139from .rich_utils import (
140+ Cmd2BaseConsole ,
136141 Cmd2ExceptionConsole ,
137142 Cmd2GeneralConsole ,
138143 RichPrintKwargs ,
@@ -1247,7 +1252,7 @@ def visible_prompt(self) -> str:
12471252
12481253 def print_to (
12491254 self ,
1250- file : IO [str ],
1255+ destination : IO [str ] | Cmd2BaseConsole ,
12511256 * objects : Any ,
12521257 sep : str = " " ,
12531258 end : str = "\n " ,
@@ -1259,13 +1264,30 @@ def print_to(
12591264 rich_print_kwargs : RichPrintKwargs | None = None ,
12601265 ** kwargs : Any , # noqa: ARG002
12611266 ) -> None :
1262- """Print objects to a given file stream.
1267+ """Print objects to a given destination ( file stream or cmd2 console) .
12631268
12641269 This method is configured for general-purpose printing. By default, it enables
12651270 soft wrap and disables Rich's automatic detection for markup, emoji, and highlighting.
12661271 These defaults can be overridden by passing explicit keyword arguments.
12671272
1268- :param file: file stream being written to
1273+ See the Rich documentation for more details on emoji codes, markup tags, and highlighting.
1274+
1275+ !!! note
1276+
1277+ To ensure consistent behavior, this method requires a file-like object or
1278+ an instance of ``Cmd2BaseConsole``.
1279+ Consoles not derived from ``Cmd2BaseConsole`` are disallowed because:
1280+
1281+ 1. **Style Control**: They ignore the global ``ALLOW_STYLE`` setting.
1282+ 2. **Theming**: They do not respect the application-wide ``APP_THEME``.
1283+ 3. **Error Handling**: They trigger a ``SystemExit`` on broken pipes.
1284+ ``Cmd2BaseConsole`` instead raises a catchable ``BrokenPipeError``,
1285+ ensuring the CLI application remains alive if a pipe is closed.
1286+
1287+ :param destination: The output target. File-like objects are automatically
1288+ wrapped in a ``Cmd2GeneralConsole`` to ensure they respect
1289+ cmd2 global settings; otherwise, this must be an
1290+ instance of ``Cmd2BaseConsole``.
12691291 :param objects: objects to print
12701292 :param sep: string to write between printed text. Defaults to " ".
12711293 :param end: string to write at end of printed text. Defaults to a newline.
@@ -1290,13 +1312,28 @@ def print_to(
12901312 :param kwargs: Arbitrary keyword arguments. This allows subclasses to extend the signature of this
12911313 method and still call `super()` without encountering unexpected keyword argument errors.
12921314 These arguments are not passed to Rich's Console.print().
1293-
1294- See the Rich documentation for more details on emoji codes, markup tags, and highlighting .
1315+ :raises TypeError: If ``destination`` is a non-cmd2 ``Console`` instance that
1316+ does not derive from ``Cmd2BaseConsole`` .
12951317 """
1318+ if isinstance (destination , Console ):
1319+ if not isinstance (destination , Cmd2BaseConsole ):
1320+ # Explicitly reject non-cmd2 consoles to ensure safe behavior
1321+ raise TypeError (
1322+ f"destination must be a 'Cmd2BaseConsole' or a file-like object, "
1323+ f"not a non-cmd2 '{ type (destination ).__name__ } '. "
1324+ "Consoles not derived from 'Cmd2BaseConsole' bypass cmd2's "
1325+ "'ALLOW_STYLE' logic, 'APP_THEME' settings, and trigger 'SystemExit' "
1326+ "on broken pipes."
1327+ )
1328+ console = destination
1329+ else :
1330+ # It's a file-like object (e.g., sys.stdout, StringIO)
1331+ console = Cmd2GeneralConsole (destination )
1332+
12961333 prepared_objects = ru .prepare_objects_for_rendering (* objects )
12971334
12981335 try :
1299- Cmd2GeneralConsole ( file ) .print (
1336+ console .print (
13001337 * prepared_objects ,
13011338 sep = sep ,
13021339 end = end ,
@@ -1313,7 +1350,7 @@ def print_to(
13131350 # writing. If you would like your application to print a
13141351 # warning message, then set the broken_pipe_warning attribute
13151352 # to the message you want printed.
1316- if self .broken_pipe_warning and file != sys .stderr :
1353+ if self .broken_pipe_warning and console . file != sys .stderr :
13171354 Cmd2GeneralConsole (sys .stderr ).print (self .broken_pipe_warning )
13181355
13191356 def poutput (
@@ -1581,17 +1618,16 @@ def ppaged(
15811618
15821619 # Check if we are outputting to a pager.
15831620 if functional_terminal and can_block :
1584- prepared_objects = ru .prepare_objects_for_rendering (* objects )
1585-
15861621 # Chopping overrides soft_wrap
15871622 if chop :
15881623 soft_wrap = True
15891624
15901625 # Generate the bytes to send to the pager
15911626 console = Cmd2GeneralConsole (self .stdout )
15921627 with console .capture () as capture :
1593- console .print (
1594- * prepared_objects ,
1628+ self .print_to (
1629+ console ,
1630+ * objects ,
15951631 sep = sep ,
15961632 end = end ,
15971633 style = style ,
0 commit comments