Repository: ClickHouse/ClickHouse
File: ci/praktika/utils.py (Python)

Code before:
        Returns the total physical memory in bytes.
        """
        try:
            # for linux
            return os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES")
        except ValueError:
            # for MacOS
            return int(subprocess.check_output(["sysctl", "-n", "hw.memsize"]).strip())

    @staticmethod
    def print_formatted_error(error_message, stdout="", stderr=""):
        stdout_lines = stdout.splitlines() if stdout else []
        stderr_lines = stderr.splitlines() if stderr else []
        print(f"ERROR: {error_message}")
        if stdout_lines:
            print("  Out:")
            for line in stdout_lines:
                print(f"     | {line}")
        if stderr_lines:
            print("  Err:")
            for line in stderr_lines:
                print(f"     | {line}")

    @staticmethod
    def print_quoted_list(list, prefix="  "):
        print(prefix + '"' + f"\"\n{prefix}\"".join(list) + '"')

    @staticmethod
    def sleep(seconds):
        time.sleep(seconds)

    @staticmethod
    def cwd():
        return str(Path.cwd())

    @staticmethod
    def cpu_count():
        return multiprocessing.cpu_count()

    @staticmethod
    def error(error_message):
        print(f"[ERROR]: {error_message}")
        sys.exit(1)

    # deprecated: unnecessary lines in traceback + ide linting issues
    # switch to regular raise Ex() inplace
    @staticmethod
    def raise_with_error(error_message, stdout="", stderr="", ex=None):
        Utils.print_formatted_error(error_message, stdout, stderr)
        raise ex or RuntimeError(error_message)


Review comment (suggestion):
`str.join(...)` will raise `TypeError` if any element in `list` is not already a string. Since callers may pass non-`str` values (now or in the future), consider coercing items to `str` (e.g., via a generator) before joining, or validating the input type and raising a clearer error.
```suggestion
        # Coerce all items to string to avoid TypeError in join when elements are not str
        items_as_str = (str(item) for item in list)
        print(prefix + '"' + f"\"\n{prefix}\"".join(items_as_str) + '"')
```

Code after:
        Returns the total physical memory in bytes.
        """
        try:
            # for linux
            return os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES")
        except ValueError:
            # for MacOS
            return int(subprocess.check_output(["sysctl", "-n", "hw.memsize"]).strip())

    @staticmethod
    def print_formatted_error(error_message, stdout="", stderr=""):
        stdout_lines = stdout.splitlines() if stdout else []
        stderr_lines = stderr.splitlines() if stderr else []
        print(f"ERROR: {error_message}")
        if stdout_lines:
            print("  Out:")
            for line in stdout_lines:
                print(f"     | {line}")
        if stderr_lines:
            print("  Err:")
            for line in stderr_lines:
                print(f"     | {line}")

    @staticmethod
    def sleep(seconds):
        time.sleep(seconds)

    @staticmethod
    def cwd():
        return str(Path.cwd())

    @staticmethod
    def cpu_count():
        return multiprocessing.cpu_count()

    @staticmethod
    def exit_with_error(error_message: str) -> None:
        print(f"ERROR: {error_message}")
        sys.exit(1)

    # deprecated: unnecessary lines in traceback + ide linting issues
    # switch to regular raise Ex() inplace
    @staticmethod
    def raise_with_error(error_message, stdout="", stderr="", ex=None):
        Utils.print_formatted_error(error_message, stdout, stderr)
        raise ex or RuntimeError(error_message)

    @staticmethod
    def timestamp():
        return datetime.now().timestamp()