diff --git a/ros2cli/ros2cli/cli.py b/ros2cli/ros2cli/cli.py index b6461d868..fb9123054 100644 --- a/ros2cli/ros2cli/cli.py +++ b/ros2cli/ros2cli/cli.py @@ -14,7 +14,10 @@ # limitations under the License. import argparse +import builtins +import functools import signal +import sys from ros2cli.command import add_subparsers_on_demand @@ -29,6 +32,14 @@ def main(*, script_name='ros2', argv=None, description=None, extension=None): description=description, formatter_class=argparse.RawDescriptionHelpFormatter ) + parser.add_argument( + '--use-python-default-buffering', + action='store_true', + default=False, + help=( + 'Do not force line buffering in stdout and instead use the python default buffering, ' + 'which might be affected by PYTHONUNBUFFERED/-u and depends on whatever stdout is ' + 'interactive or not')) # add arguments for command extension(s) if extension: @@ -53,6 +64,17 @@ def main(*, script_name='ros2', argv=None, description=None, extension=None): # parse the command line arguments args = parser.parse_args(args=argv) + if not args.use_python_default_buffering: + # Make the output always line buffered. + # TextIoWrapper has a reconfigure() method, call that if available. + # https://docs.python.org/3/library/io.html#io.TextIOWrapper.reconfigure + try: + sys.stdout.reconfigure(line_buffering=True) + except AttributeError: + # if stdout is not a TextIoWrapper instance, or we're using python older than 3.7, + # force line buffering by patching print + builtins.print = functools.partial(print, flush=True) + if extension is None: # get extension identified by the passed command (if available) extension = getattr(args, selected_extension_key, None) diff --git a/ros2param/test/test_verb_dump.py b/ros2param/test/test_verb_dump.py index 2ff243606..6fe54d942 100644 --- a/ros2param/test/test_verb_dump.py +++ b/ros2param/test/test_verb_dump.py @@ -233,7 +233,7 @@ def test_verb_dump_print(self): expected_lines=[ "WARNING: '--print' is deprecated; this utility prints to stdout by default" ], - text=param_dump_command.output, + text=param_dump_command.stderr, strict=True ) @@ -250,7 +250,7 @@ def test_verb_dump_output(self): expected_lines=[ "WARNING: '--output-dir' is deprecated; use redirection to save to a file" ], - text=param_dump_command.output, + text=param_dump_command.stderr, strict=True ) # Compare generated parameter file against expected