Example #1
0
def initialize_stdio_raw(
    global_level: LogLevel,
    log_show_rust_3rdparty: bool,
    show_target: bool,
    log_levels_by_target: dict[str, LogLevel],
    print_stacktrace: bool,
    ignore_warnings: list[str],
    pants_workdir: str,
) -> Iterator[None]:
    literal_filters = []
    regex_filters = []
    for filt in ignore_warnings:
        if filt.startswith("$regex$"):
            regex_filters.append(strip_prefix(filt, "$regex$"))
        else:
            literal_filters.append(filt)

    # Set the pants log destination.
    log_path = str(pants_log_path(PurePath(pants_workdir)))
    safe_mkdir_for(log_path)

    # Initialize thread-local stdio, and replace sys.std* with proxies.
    original_stdin, original_stdout, original_stderr = sys.stdin, sys.stdout, sys.stderr
    try:
        raw_stdin, sys.stdout, sys.stderr = native_engine.stdio_initialize(
            global_level.level,
            log_show_rust_3rdparty,
            show_target,
            {k: v.level
             for k, v in log_levels_by_target.items()},
            tuple(literal_filters),
            tuple(regex_filters),
            log_path,
        )
        sys.stdin = TextIOWrapper(
            BufferedReader(raw_stdin),
            # NB: We set the default encoding explicitly to bypass logic in the TextIOWrapper
            # constructor that would poke the underlying file (which is not valid until a
            # `stdio_destination` is set).
            encoding=locale.getpreferredencoding(False),
        )

        sys.__stdin__, sys.__stdout__, sys.__stderr__ = sys.stdin, sys.stdout, sys.stderr  # type: ignore[assignment]
        # Install a Python logger that will route through the Rust logger.
        with _python_logging_setup(global_level,
                                   log_levels_by_target,
                                   print_stacktrace=print_stacktrace):
            yield
    finally:
        sys.stdin, sys.stdout, sys.stderr = original_stdin, original_stdout, original_stderr
        sys.__stdin__, sys.__stdout__, sys.__stderr__ = sys.stdin, sys.stdout, sys.stderr  # type: ignore[assignment]
Example #2
0
def initialize_stdio(
        global_bootstrap_options: OptionValueContainer) -> Iterator[None]:
    """Mutates sys.std* and logging to route stdio for a Pants process to thread local destinations.

    In this context, `sys.std*` and logging handlers will route through Rust code that uses
    thread-local information to decide whether to write to a file, or to stdio file handles.

    To control the stdio destination set by this method, use the `stdio_destination` context manager.

    This is called in two different processes:
    * PantsRunner, after it has determined that LocalPantsRunner will be running in process, and
      immediately before setting a `stdio_destination` for the remainder of the run.
    * PantsDaemon, immediately on startup. The process will then default to sending stdio to the log
      until client connections arrive, at which point `stdio_destination` is used per-connection.
    """
    global_level = global_bootstrap_options.level
    log_show_rust_3rdparty = global_bootstrap_options.log_show_rust_3rdparty
    use_color = global_bootstrap_options.colors
    show_target = global_bootstrap_options.show_log_target
    log_levels_by_target = _get_log_levels_by_target(global_bootstrap_options)
    message_regex_filters = global_bootstrap_options.ignore_pants_warnings
    print_stacktrace = global_bootstrap_options.print_stacktrace

    # Set the pants log destination.
    deprecated_log_path = os.path.join(global_bootstrap_options.pants_workdir,
                                       "pantsd", "pantsd.log")
    log_path = os.path.join(global_bootstrap_options.pants_workdir,
                            "pants.log")
    safe_mkdir_for(deprecated_log_path)
    safe_mkdir_for(log_path)
    # NB: We append to the deprecated log location with a deprecated conditional that never
    # triggers, because there is nothing that the user can do about the deprecation.
    deprecated_conditional(
        predicate=lambda: False,
        removal_version="2.5.0.dev0",
        entity_description=f"Logging to {deprecated_log_path}",
        hint_message=f"Refer to {log_path} instead.",
    )
    with open(deprecated_log_path, "a") as a:
        a.write(
            f"This log location is deprecated: please refer to {log_path} instead.\n"
        )

    # Initialize thread-local stdio, and replace sys.std* with proxies.
    original_stdin, original_stdout, original_stderr = sys.stdin, sys.stdout, sys.stderr
    try:
        sys.stdin, sys.stdout, sys.stderr = native_engine.stdio_initialize(
            global_level.level,
            log_show_rust_3rdparty,
            use_color,
            show_target,
            {k: v.level
             for k, v in log_levels_by_target.items()},
            tuple(message_regex_filters),
            log_path,
        )
        # Install a Python logger that will route through the Rust logger.
        with _python_logging_setup(global_level, print_stacktrace):
            yield
    finally:
        sys.stdin, sys.stdout, sys.stderr = original_stdin, original_stdout, original_stderr
Example #3
0
def initialize_stdio(
        global_bootstrap_options: OptionValueContainer) -> Iterator[None]:
    """Mutates sys.std* and logging to route stdio for a Pants process to thread local destinations.

    In this context, `sys.std*` and logging handlers will route through Rust code that uses
    thread-local information to decide whether to write to a file, or to stdio file handles.

    To control the stdio destination set by this method, use the `stdio_destination` context manager.

    This is called in two different processes:
    * PantsRunner, after it has determined that LocalPantsRunner will be running in process, and
      immediately before setting a `stdio_destination` for the remainder of the run.
    * PantsDaemon, immediately on startup. The process will then default to sending stdio to the log
      until client connections arrive, at which point `stdio_destination` is used per-connection.
    """
    global_level = global_bootstrap_options.level
    log_show_rust_3rdparty = global_bootstrap_options.log_show_rust_3rdparty
    show_target = global_bootstrap_options.show_log_target
    log_levels_by_target = _get_log_levels_by_target(global_bootstrap_options)
    print_stacktrace = global_bootstrap_options.print_stacktrace
    local_cleanup = global_bootstrap_options.process_execution_local_cleanup

    literal_filters = []
    regex_filters = []
    for filt in cast("list[str]", global_bootstrap_options.ignore_warnings):
        if filt.startswith("$regex$"):
            regex_filters.append(strip_prefix(filt, "$regex$"))
        else:
            literal_filters.append(filt)

    # Set the pants log destination.
    log_path = str(
        pants_log_path(PurePath(global_bootstrap_options.pants_workdir)))
    safe_mkdir_for(log_path)

    # Initialize thread-local stdio, and replace sys.std* with proxies.
    original_stdin, original_stdout, original_stderr = sys.stdin, sys.stdout, sys.stderr
    try:
        raw_stdin, sys.stdout, sys.stderr = native_engine.stdio_initialize(
            global_level.level,
            log_show_rust_3rdparty,
            show_target,
            {k: v.level
             for k, v in log_levels_by_target.items()},
            tuple(literal_filters),
            tuple(regex_filters),
            log_path,
        )
        sys.stdin = TextIOWrapper(
            BufferedReader(raw_stdin),
            # NB: We set the default encoding explicitly to bypass logic in the TextIOWrapper
            # constructor that would poke the underlying file (which is not valid until a
            # `stdio_destination` is set).
            encoding=locale.getpreferredencoding(False),
        )

        sys.__stdin__, sys.__stdout__, sys.__stderr__ = sys.stdin, sys.stdout, sys.stderr
        # Install a Python logger that will route through the Rust logger.
        with _python_logging_setup(global_level,
                                   print_stacktrace=print_stacktrace,
                                   local_cleanup=local_cleanup):
            yield
    finally:
        sys.stdin, sys.stdout, sys.stderr = original_stdin, original_stdout, original_stderr
        sys.__stdin__, sys.__stdout__, sys.__stderr__ = sys.stdin, sys.stdout, sys.stderr