We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[feature] Don't add escape sequences to stdout of (some) query commands, regardless of CLICOLOR_FORCE
### What is your suggestion?

Hi!

My use case: I am running various conan commands in a wrapper script. The wrapper is using its own buffering when running subprocesses, so when I run the script in the terminal, conan doesn't know that it actually runs in terminal, and disables colors in logs. I set CLICOLOR_FORCE env variable when I want to see colored logs, which works nicely for me.

Sadly, when I want to capture stdout of a command and do something with it, CLICOLOR_FORCE adds unwanted escape sequences and breaks my script:

```bash
$ conan list 'zlib/*' --format=json | cat -A
{$
    "Local Cache": {$
        "zlib/1.2.13": {}$
    }$
}$
$ CLICOLOR_FORCE=1 conan list 'zlib/*' --format=json | cat -A
{$
    "Local Cache": {$
        "zlib/1.2.13": {}$
    }$
}^[[0m$
```

Same can be observed if I run simple `conan config home`. This is kinda expected since I add a variable to force colors, but JSON output format is meant to be processed automatically, so I think it shouldn't be touched with color decorations at all.

### Have you read the CONTRIBUTING guide?

- [X] I've read the CONTRIBUTING guide

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `conan/api/output.py`
Content:
```
1 import sys
2 
3 from colorama import Fore, Style
4 
5 from conans.client.userio import color_enabled
6 from conans.errors import ConanException
7 from conans.util.env import get_env
8 
9 LEVEL_QUIET = 80  # -q
10 LEVEL_ERROR = 70  # Errors
11 LEVEL_WARNING = 60  # Warnings
12 LEVEL_NOTICE = 50  # Important messages to attract user attention.
13 LEVEL_STATUS = 40  # Default - The main interesting messages that users might be interested in.
14 LEVEL_VERBOSE = 30  # -v  Detailed informational messages.
15 LEVEL_DEBUG = 20  # -vv Closely related to internal implementation details
16 LEVEL_TRACE = 10  # -vvv Fine-grained messages with very low-level implementation details
17 
18 
19 class Color(object):
20     """ Wrapper around colorama colors that are undefined in importing
21     """
22     RED = Fore.RED  # @UndefinedVariable
23     WHITE = Fore.WHITE  # @UndefinedVariable
24     CYAN = Fore.CYAN  # @UndefinedVariable
25     GREEN = Fore.GREEN  # @UndefinedVariable
26     MAGENTA = Fore.MAGENTA  # @UndefinedVariable
27     BLUE = Fore.BLUE  # @UndefinedVariable
28     YELLOW = Fore.YELLOW  # @UndefinedVariable
29     BLACK = Fore.BLACK  # @UndefinedVariable
30 
31     BRIGHT_RED = Style.BRIGHT + Fore.RED  # @UndefinedVariable
32     BRIGHT_BLUE = Style.BRIGHT + Fore.BLUE  # @UndefinedVariable
33     BRIGHT_YELLOW = Style.BRIGHT + Fore.YELLOW  # @UndefinedVariable
34     BRIGHT_GREEN = Style.BRIGHT + Fore.GREEN  # @UndefinedVariable
35     BRIGHT_CYAN = Style.BRIGHT + Fore.CYAN  # @UndefinedVariable
36     BRIGHT_WHITE = Style.BRIGHT + Fore.WHITE  # @UndefinedVariable
37     BRIGHT_MAGENTA = Style.BRIGHT + Fore.MAGENTA  # @UndefinedVariable
38 
39 
40 if get_env("CONAN_COLOR_DARK", 0):
41     Color.WHITE = Fore.BLACK
42     Color.CYAN = Fore.BLUE
43     Color.YELLOW = Fore.MAGENTA
44     Color.BRIGHT_WHITE = Fore.BLACK
45     Color.BRIGHT_CYAN = Fore.BLUE
46     Color.BRIGHT_YELLOW = Fore.MAGENTA
47     Color.BRIGHT_GREEN = Fore.GREEN
48 
49 
50 class ConanOutput:
51     # Singleton
52     _conan_output_level = LEVEL_STATUS
53     _silent_warn_tags = []
54 
55     def __init__(self, scope=""):
56         self.stream = sys.stderr
57         self._scope = scope
58         # FIXME:  This is needed because in testing we are redirecting the sys.stderr to a buffer
59         #         stream to capture it, so colorama is not there to strip the color bytes
60         self._color = color_enabled(self.stream)
61 
62     @classmethod
63     def define_silence_warnings(cls, warnings):
64         cls._silent_warn_tags = warnings or []
65 
66     @classmethod
67     def define_log_level(cls, v):
68         """
69         Translates the verbosity level entered by a Conan command. If it's `None` (-v),
70         it will be defaulted to `verbose` level.
71 
72         :param v: `str` or `None`, where `None` is the same as `verbose`.
73         """
74         try:
75             level = {"quiet": LEVEL_QUIET,  # -vquiet 80
76                      "error": LEVEL_ERROR,  # -verror 70
77                      "warning": LEVEL_WARNING,  # -vwaring 60
78                      "notice": LEVEL_NOTICE,  # -vnotice 50
79                      "status": LEVEL_STATUS,  # -vstatus 40
80                      None: LEVEL_VERBOSE,  # -v 30
81                      "verbose": LEVEL_VERBOSE,  # -vverbose 30
82                      "debug": LEVEL_DEBUG,  # -vdebug 20
83                      "v": LEVEL_DEBUG,  # -vv 20
84                      "trace": LEVEL_TRACE,  # -vtrace 10
85                      "vv": LEVEL_TRACE  # -vvv 10
86                      }[v]
87         except KeyError:
88             raise ConanException(f"Invalid argument '-v{v}'")
89         else:
90             cls._conan_output_level = level
91 
92     @classmethod
93     def level_allowed(cls, level):
94         return cls._conan_output_level <= level
95 
96     @property
97     def color(self):
98         return self._color
99 
100     @property
101     def scope(self):
102         return self._scope
103 
104     @scope.setter
105     def scope(self, out_scope):
106         self._scope = out_scope
107 
108     @property
109     def is_terminal(self):
110         return hasattr(self.stream, "isatty") and self.stream.isatty()
111 
112     def writeln(self, data, fg=None, bg=None):
113         return self.write(data, fg, bg, newline=True)
114 
115     def write(self, data, fg=None, bg=None, newline=False):
116         if self._conan_output_level > LEVEL_NOTICE:
117             return self
118         if self._color and (fg or bg):
119             data = "%s%s%s%s" % (fg or '', bg or '', data, Style.RESET_ALL)
120 
121         if newline:
122             data = "%s\n" % data
123         self.stream.write(data)
124         self.stream.flush()
125         return self
126 
127     def rewrite_line(self, line):
128         tmp_color = self._color
129         self._color = False
130         total_size = 70
131         limit_size = total_size // 2 - 3
132         if len(line) > total_size:
133             line = line[0:limit_size] + " ... " + line[-limit_size:]
134         self.write("\r%s%s" % (line, " " * (total_size - len(line))))
135         self.stream.flush()
136         self._color = tmp_color
137 
138     def _write_message(self, msg, fg=None, bg=None):
139         if isinstance(msg, dict):
140             # For traces we can receive a dict already, we try to transform then into more natural
141             # text
142             msg = ", ".join([f"{k}: {v}" for k, v in msg.items()])
143             msg = "=> {}".format(msg)
144             # msg = json.dumps(msg, sort_keys=True, default=json_encoder)
145 
146         ret = ""
147         if self._scope:
148             if self._color:
149                 ret = "{}{}{}:{} ".format(fg or '', bg or '', self.scope, Style.RESET_ALL)
150             else:
151                 ret = "{}: ".format(self._scope)
152 
153         if self._color:
154             ret += "{}{}{}{}".format(fg or '', bg or '', msg, Style.RESET_ALL)
155         else:
156             ret += "{}".format(msg)
157 
158         self.stream.write("{}\n".format(ret))
159         self.stream.flush()
160 
161     def trace(self, msg):
162         if self._conan_output_level <= LEVEL_TRACE:
163             self._write_message(msg, fg=Color.BRIGHT_WHITE)
164         return self
165 
166     def debug(self, msg):
167         if self._conan_output_level <= LEVEL_DEBUG:
168             self._write_message(msg)
169         return self
170 
171     def verbose(self, msg, fg=None, bg=None):
172         if self._conan_output_level <= LEVEL_VERBOSE:
173             self._write_message(msg, fg=fg, bg=bg)
174         return self
175 
176     def status(self, msg, fg=None, bg=None):
177         if self._conan_output_level <= LEVEL_STATUS:
178             self._write_message(msg, fg=fg, bg=bg)
179         return self
180 
181     # Remove in a later refactor of all the output.info calls
182     info = status
183 
184     def title(self, msg):
185         if self._conan_output_level <= LEVEL_NOTICE:
186             self._write_message("\n======== {} ========".format(msg),
187                                 fg=Color.BRIGHT_MAGENTA)
188         return self
189 
190     def subtitle(self, msg):
191         if self._conan_output_level <= LEVEL_NOTICE:
192             self._write_message("\n-------- {} --------".format(msg),
193                                 fg=Color.BRIGHT_MAGENTA)
194         return self
195 
196     def highlight(self, msg):
197         if self._conan_output_level <= LEVEL_NOTICE:
198             self._write_message(msg, fg=Color.BRIGHT_MAGENTA)
199         return self
200 
201     def success(self, msg):
202         if self._conan_output_level <= LEVEL_NOTICE:
203             self._write_message(msg, fg=Color.BRIGHT_GREEN)
204         return self
205 
206     def warning(self, msg, warn_tag=None):
207         if self._conan_output_level <= LEVEL_WARNING:
208             if warn_tag is not None and warn_tag in self._silent_warn_tags:
209                 return self
210             warn_tag_msg = "" if warn_tag is None else f"{warn_tag}: "
211             self._write_message(f"WARN: {warn_tag_msg}{msg}", Color.YELLOW)
212         return self
213 
214     def error(self, msg):
215         if self._conan_output_level <= LEVEL_ERROR:
216             self._write_message("ERROR: {}".format(msg), Color.RED)
217         return self
218 
219     def flush(self):
220         self.stream.flush()
221 
222 
223 def cli_out_write(data, fg=None, bg=None, endline="\n", indentation=0):
224     """
225     Output to be used by formatters to dump information to stdout
226     """
227 
228     fg_ = fg or ''
229     bg_ = bg or ''
230     if color_enabled(sys.stdout):
231         data = f"{' ' * indentation}{fg_}{bg_}{data}{Style.RESET_ALL}{endline}"
232     else:
233         data = f"{' ' * indentation}{data}{endline}"
234 
235     sys.stdout.write(data)
236
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/conan/api/output.py b/conan/api/output.py
--- a/conan/api/output.py
+++ b/conan/api/output.py
@@ -227,7 +227,7 @@
 
     fg_ = fg or ''
     bg_ = bg or ''
-    if color_enabled(sys.stdout):
+    if (fg or bg) and color_enabled(sys.stdout):
         data = f"{' ' * indentation}{fg_}{bg_}{data}{Style.RESET_ALL}{endline}"
     else:
         data = f"{' ' * indentation}{data}{endline}"

{"golden_diff": "diff --git a/conan/api/output.py b/conan/api/output.py\n--- a/conan/api/output.py\n+++ b/conan/api/output.py\n@@ -227,7 +227,7 @@\n \n     fg_ = fg or ''\n     bg_ = bg or ''\n-    if color_enabled(sys.stdout):\n+    if (fg or bg) and color_enabled(sys.stdout):\n         data = f\"{' ' * indentation}{fg_}{bg_}{data}{Style.RESET_ALL}{endline}\"\n     else:\n         data = f\"{' ' * indentation}{data}{endline}\"\n", "issue": "[feature] Don't add escape sequences to stdout of (some) query commands, regardless of CLICOLOR_FORCE\n### What is your suggestion?\n\nHi!\r\n\r\nMy use case: I am running various conan commands in a wrapper script. The wrapper is using its own buffering when running subprocesses, so when I run the script in the terminal, conan doesn't know that it actually runs in terminal, and disables colors in logs. I set CLICOLOR_FORCE env variable when I want to see colored logs, which works nicely for me.\r\n\r\nSadly, when I want to capture stdout of a command and do something with it, CLICOLOR_FORCE adds unwanted escape sequences and breaks my script:\r\n\r\n```bash\r\n$ conan list 'zlib/*' --format=json | cat -A\r\n{$\r\n    \"Local Cache\": {$\r\n        \"zlib/1.2.13\": {}$\r\n    }$\r\n}$\r\n$ CLICOLOR_FORCE=1 conan list 'zlib/*' --format=json | cat -A\r\n{$\r\n    \"Local Cache\": {$\r\n        \"zlib/1.2.13\": {}$\r\n    }$\r\n}^[[0m$\r\n```\r\n\r\nSame can be observed if I run simple `conan config home`. This is kinda expected since I add a variable to force colors, but JSON output format is meant to be processed automatically, so I think it shouldn't be touched with color decorations at all.\n\n### Have you read the CONTRIBUTING guide?\n\n- [X] I've read the CONTRIBUTING guide\n", "before_files": [{"content": "import sys\n\nfrom colorama import Fore, Style\n\nfrom conans.client.userio import color_enabled\nfrom conans.errors import ConanException\nfrom conans.util.env import get_env\n\nLEVEL_QUIET = 80  # -q\nLEVEL_ERROR = 70  # Errors\nLEVEL_WARNING = 60  # Warnings\nLEVEL_NOTICE = 50  # Important messages to attract user attention.\nLEVEL_STATUS = 40  # Default - The main interesting messages that users might be interested in.\nLEVEL_VERBOSE = 30  # -v  Detailed informational messages.\nLEVEL_DEBUG = 20  # -vv Closely related to internal implementation details\nLEVEL_TRACE = 10  # -vvv Fine-grained messages with very low-level implementation details\n\n\nclass Color(object):\n    \"\"\" Wrapper around colorama colors that are undefined in importing\n    \"\"\"\n    RED = Fore.RED  # @UndefinedVariable\n    WHITE = Fore.WHITE  # @UndefinedVariable\n    CYAN = Fore.CYAN  # @UndefinedVariable\n    GREEN = Fore.GREEN  # @UndefinedVariable\n    MAGENTA = Fore.MAGENTA  # @UndefinedVariable\n    BLUE = Fore.BLUE  # @UndefinedVariable\n    YELLOW = Fore.YELLOW  # @UndefinedVariable\n    BLACK = Fore.BLACK  # @UndefinedVariable\n\n    BRIGHT_RED = Style.BRIGHT + Fore.RED  # @UndefinedVariable\n    BRIGHT_BLUE = Style.BRIGHT + Fore.BLUE  # @UndefinedVariable\n    BRIGHT_YELLOW = Style.BRIGHT + Fore.YELLOW  # @UndefinedVariable\n    BRIGHT_GREEN = Style.BRIGHT + Fore.GREEN  # @UndefinedVariable\n    BRIGHT_CYAN = Style.BRIGHT + Fore.CYAN  # @UndefinedVariable\n    BRIGHT_WHITE = Style.BRIGHT + Fore.WHITE  # @UndefinedVariable\n    BRIGHT_MAGENTA = Style.BRIGHT + Fore.MAGENTA  # @UndefinedVariable\n\n\nif get_env(\"CONAN_COLOR_DARK\", 0):\n    Color.WHITE = Fore.BLACK\n    Color.CYAN = Fore.BLUE\n    Color.YELLOW = Fore.MAGENTA\n    Color.BRIGHT_WHITE = Fore.BLACK\n    Color.BRIGHT_CYAN = Fore.BLUE\n    Color.BRIGHT_YELLOW = Fore.MAGENTA\n    Color.BRIGHT_GREEN = Fore.GREEN\n\n\nclass ConanOutput:\n    # Singleton\n    _conan_output_level = LEVEL_STATUS\n    _silent_warn_tags = []\n\n    def __init__(self, scope=\"\"):\n        self.stream = sys.stderr\n        self._scope = scope\n        # FIXME:  This is needed because in testing we are redirecting the sys.stderr to a buffer\n        #         stream to capture it, so colorama is not there to strip the color bytes\n        self._color = color_enabled(self.stream)\n\n    @classmethod\n    def define_silence_warnings(cls, warnings):\n        cls._silent_warn_tags = warnings or []\n\n    @classmethod\n    def define_log_level(cls, v):\n        \"\"\"\n        Translates the verbosity level entered by a Conan command. If it's `None` (-v),\n        it will be defaulted to `verbose` level.\n\n        :param v: `str` or `None`, where `None` is the same as `verbose`.\n        \"\"\"\n        try:\n            level = {\"quiet\": LEVEL_QUIET,  # -vquiet 80\n                     \"error\": LEVEL_ERROR,  # -verror 70\n                     \"warning\": LEVEL_WARNING,  # -vwaring 60\n                     \"notice\": LEVEL_NOTICE,  # -vnotice 50\n                     \"status\": LEVEL_STATUS,  # -vstatus 40\n                     None: LEVEL_VERBOSE,  # -v 30\n                     \"verbose\": LEVEL_VERBOSE,  # -vverbose 30\n                     \"debug\": LEVEL_DEBUG,  # -vdebug 20\n                     \"v\": LEVEL_DEBUG,  # -vv 20\n                     \"trace\": LEVEL_TRACE,  # -vtrace 10\n                     \"vv\": LEVEL_TRACE  # -vvv 10\n                     }[v]\n        except KeyError:\n            raise ConanException(f\"Invalid argument '-v{v}'\")\n        else:\n            cls._conan_output_level = level\n\n    @classmethod\n    def level_allowed(cls, level):\n        return cls._conan_output_level <= level\n\n    @property\n    def color(self):\n        return self._color\n\n    @property\n    def scope(self):\n        return self._scope\n\n    @scope.setter\n    def scope(self, out_scope):\n        self._scope = out_scope\n\n    @property\n    def is_terminal(self):\n        return hasattr(self.stream, \"isatty\") and self.stream.isatty()\n\n    def writeln(self, data, fg=None, bg=None):\n        return self.write(data, fg, bg, newline=True)\n\n    def write(self, data, fg=None, bg=None, newline=False):\n        if self._conan_output_level > LEVEL_NOTICE:\n            return self\n        if self._color and (fg or bg):\n            data = \"%s%s%s%s\" % (fg or '', bg or '', data, Style.RESET_ALL)\n\n        if newline:\n            data = \"%s\\n\" % data\n        self.stream.write(data)\n        self.stream.flush()\n        return self\n\n    def rewrite_line(self, line):\n        tmp_color = self._color\n        self._color = False\n        total_size = 70\n        limit_size = total_size // 2 - 3\n        if len(line) > total_size:\n            line = line[0:limit_size] + \" ... \" + line[-limit_size:]\n        self.write(\"\\r%s%s\" % (line, \" \" * (total_size - len(line))))\n        self.stream.flush()\n        self._color = tmp_color\n\n    def _write_message(self, msg, fg=None, bg=None):\n        if isinstance(msg, dict):\n            # For traces we can receive a dict already, we try to transform then into more natural\n            # text\n            msg = \", \".join([f\"{k}: {v}\" for k, v in msg.items()])\n            msg = \"=> {}\".format(msg)\n            # msg = json.dumps(msg, sort_keys=True, default=json_encoder)\n\n        ret = \"\"\n        if self._scope:\n            if self._color:\n                ret = \"{}{}{}:{} \".format(fg or '', bg or '', self.scope, Style.RESET_ALL)\n            else:\n                ret = \"{}: \".format(self._scope)\n\n        if self._color:\n            ret += \"{}{}{}{}\".format(fg or '', bg or '', msg, Style.RESET_ALL)\n        else:\n            ret += \"{}\".format(msg)\n\n        self.stream.write(\"{}\\n\".format(ret))\n        self.stream.flush()\n\n    def trace(self, msg):\n        if self._conan_output_level <= LEVEL_TRACE:\n            self._write_message(msg, fg=Color.BRIGHT_WHITE)\n        return self\n\n    def debug(self, msg):\n        if self._conan_output_level <= LEVEL_DEBUG:\n            self._write_message(msg)\n        return self\n\n    def verbose(self, msg, fg=None, bg=None):\n        if self._conan_output_level <= LEVEL_VERBOSE:\n            self._write_message(msg, fg=fg, bg=bg)\n        return self\n\n    def status(self, msg, fg=None, bg=None):\n        if self._conan_output_level <= LEVEL_STATUS:\n            self._write_message(msg, fg=fg, bg=bg)\n        return self\n\n    # Remove in a later refactor of all the output.info calls\n    info = status\n\n    def title(self, msg):\n        if self._conan_output_level <= LEVEL_NOTICE:\n            self._write_message(\"\\n======== {} ========\".format(msg),\n                                fg=Color.BRIGHT_MAGENTA)\n        return self\n\n    def subtitle(self, msg):\n        if self._conan_output_level <= LEVEL_NOTICE:\n            self._write_message(\"\\n-------- {} --------\".format(msg),\n                                fg=Color.BRIGHT_MAGENTA)\n        return self\n\n    def highlight(self, msg):\n        if self._conan_output_level <= LEVEL_NOTICE:\n            self._write_message(msg, fg=Color.BRIGHT_MAGENTA)\n        return self\n\n    def success(self, msg):\n        if self._conan_output_level <= LEVEL_NOTICE:\n            self._write_message(msg, fg=Color.BRIGHT_GREEN)\n        return self\n\n    def warning(self, msg, warn_tag=None):\n        if self._conan_output_level <= LEVEL_WARNING:\n            if warn_tag is not None and warn_tag in self._silent_warn_tags:\n                return self\n            warn_tag_msg = \"\" if warn_tag is None else f\"{warn_tag}: \"\n            self._write_message(f\"WARN: {warn_tag_msg}{msg}\", Color.YELLOW)\n        return self\n\n    def error(self, msg):\n        if self._conan_output_level <= LEVEL_ERROR:\n            self._write_message(\"ERROR: {}\".format(msg), Color.RED)\n        return self\n\n    def flush(self):\n        self.stream.flush()\n\n\ndef cli_out_write(data, fg=None, bg=None, endline=\"\\n\", indentation=0):\n    \"\"\"\n    Output to be used by formatters to dump information to stdout\n    \"\"\"\n\n    fg_ = fg or ''\n    bg_ = bg or ''\n    if color_enabled(sys.stdout):\n        data = f\"{' ' * indentation}{fg_}{bg_}{data}{Style.RESET_ALL}{endline}\"\n    else:\n        data = f\"{' ' * indentation}{data}{endline}\"\n\n    sys.stdout.write(data)\n", "path": "conan/api/output.py"}], "after_files": [{"content": "import sys\n\nfrom colorama import Fore, Style\n\nfrom conans.client.userio import color_enabled\nfrom conans.errors import ConanException\nfrom conans.util.env import get_env\n\nLEVEL_QUIET = 80  # -q\nLEVEL_ERROR = 70  # Errors\nLEVEL_WARNING = 60  # Warnings\nLEVEL_NOTICE = 50  # Important messages to attract user attention.\nLEVEL_STATUS = 40  # Default - The main interesting messages that users might be interested in.\nLEVEL_VERBOSE = 30  # -v  Detailed informational messages.\nLEVEL_DEBUG = 20  # -vv Closely related to internal implementation details\nLEVEL_TRACE = 10  # -vvv Fine-grained messages with very low-level implementation details\n\n\nclass Color(object):\n    \"\"\" Wrapper around colorama colors that are undefined in importing\n    \"\"\"\n    RED = Fore.RED  # @UndefinedVariable\n    WHITE = Fore.WHITE  # @UndefinedVariable\n    CYAN = Fore.CYAN  # @UndefinedVariable\n    GREEN = Fore.GREEN  # @UndefinedVariable\n    MAGENTA = Fore.MAGENTA  # @UndefinedVariable\n    BLUE = Fore.BLUE  # @UndefinedVariable\n    YELLOW = Fore.YELLOW  # @UndefinedVariable\n    BLACK = Fore.BLACK  # @UndefinedVariable\n\n    BRIGHT_RED = Style.BRIGHT + Fore.RED  # @UndefinedVariable\n    BRIGHT_BLUE = Style.BRIGHT + Fore.BLUE  # @UndefinedVariable\n    BRIGHT_YELLOW = Style.BRIGHT + Fore.YELLOW  # @UndefinedVariable\n    BRIGHT_GREEN = Style.BRIGHT + Fore.GREEN  # @UndefinedVariable\n    BRIGHT_CYAN = Style.BRIGHT + Fore.CYAN  # @UndefinedVariable\n    BRIGHT_WHITE = Style.BRIGHT + Fore.WHITE  # @UndefinedVariable\n    BRIGHT_MAGENTA = Style.BRIGHT + Fore.MAGENTA  # @UndefinedVariable\n\n\nif get_env(\"CONAN_COLOR_DARK\", 0):\n    Color.WHITE = Fore.BLACK\n    Color.CYAN = Fore.BLUE\n    Color.YELLOW = Fore.MAGENTA\n    Color.BRIGHT_WHITE = Fore.BLACK\n    Color.BRIGHT_CYAN = Fore.BLUE\n    Color.BRIGHT_YELLOW = Fore.MAGENTA\n    Color.BRIGHT_GREEN = Fore.GREEN\n\n\nclass ConanOutput:\n    # Singleton\n    _conan_output_level = LEVEL_STATUS\n    _silent_warn_tags = []\n\n    def __init__(self, scope=\"\"):\n        self.stream = sys.stderr\n        self._scope = scope\n        # FIXME:  This is needed because in testing we are redirecting the sys.stderr to a buffer\n        #         stream to capture it, so colorama is not there to strip the color bytes\n        self._color = color_enabled(self.stream)\n\n    @classmethod\n    def define_silence_warnings(cls, warnings):\n        cls._silent_warn_tags = warnings or []\n\n    @classmethod\n    def define_log_level(cls, v):\n        \"\"\"\n        Translates the verbosity level entered by a Conan command. If it's `None` (-v),\n        it will be defaulted to `verbose` level.\n\n        :param v: `str` or `None`, where `None` is the same as `verbose`.\n        \"\"\"\n        try:\n            level = {\"quiet\": LEVEL_QUIET,  # -vquiet 80\n                     \"error\": LEVEL_ERROR,  # -verror 70\n                     \"warning\": LEVEL_WARNING,  # -vwaring 60\n                     \"notice\": LEVEL_NOTICE,  # -vnotice 50\n                     \"status\": LEVEL_STATUS,  # -vstatus 40\n                     None: LEVEL_VERBOSE,  # -v 30\n                     \"verbose\": LEVEL_VERBOSE,  # -vverbose 30\n                     \"debug\": LEVEL_DEBUG,  # -vdebug 20\n                     \"v\": LEVEL_DEBUG,  # -vv 20\n                     \"trace\": LEVEL_TRACE,  # -vtrace 10\n                     \"vv\": LEVEL_TRACE  # -vvv 10\n                     }[v]\n        except KeyError:\n            raise ConanException(f\"Invalid argument '-v{v}'\")\n        else:\n            cls._conan_output_level = level\n\n    @classmethod\n    def level_allowed(cls, level):\n        return cls._conan_output_level <= level\n\n    @property\n    def color(self):\n        return self._color\n\n    @property\n    def scope(self):\n        return self._scope\n\n    @scope.setter\n    def scope(self, out_scope):\n        self._scope = out_scope\n\n    @property\n    def is_terminal(self):\n        return hasattr(self.stream, \"isatty\") and self.stream.isatty()\n\n    def writeln(self, data, fg=None, bg=None):\n        return self.write(data, fg, bg, newline=True)\n\n    def write(self, data, fg=None, bg=None, newline=False):\n        if self._conan_output_level > LEVEL_NOTICE:\n            return self\n        if self._color and (fg or bg):\n            data = \"%s%s%s%s\" % (fg or '', bg or '', data, Style.RESET_ALL)\n\n        if newline:\n            data = \"%s\\n\" % data\n        self.stream.write(data)\n        self.stream.flush()\n        return self\n\n    def rewrite_line(self, line):\n        tmp_color = self._color\n        self._color = False\n        total_size = 70\n        limit_size = total_size // 2 - 3\n        if len(line) > total_size:\n            line = line[0:limit_size] + \" ... \" + line[-limit_size:]\n        self.write(\"\\r%s%s\" % (line, \" \" * (total_size - len(line))))\n        self.stream.flush()\n        self._color = tmp_color\n\n    def _write_message(self, msg, fg=None, bg=None):\n        if isinstance(msg, dict):\n            # For traces we can receive a dict already, we try to transform then into more natural\n            # text\n            msg = \", \".join([f\"{k}: {v}\" for k, v in msg.items()])\n            msg = \"=> {}\".format(msg)\n            # msg = json.dumps(msg, sort_keys=True, default=json_encoder)\n\n        ret = \"\"\n        if self._scope:\n            if self._color:\n                ret = \"{}{}{}:{} \".format(fg or '', bg or '', self.scope, Style.RESET_ALL)\n            else:\n                ret = \"{}: \".format(self._scope)\n\n        if self._color:\n            ret += \"{}{}{}{}\".format(fg or '', bg or '', msg, Style.RESET_ALL)\n        else:\n            ret += \"{}\".format(msg)\n\n        self.stream.write(\"{}\\n\".format(ret))\n        self.stream.flush()\n\n    def trace(self, msg):\n        if self._conan_output_level <= LEVEL_TRACE:\n            self._write_message(msg, fg=Color.BRIGHT_WHITE)\n        return self\n\n    def debug(self, msg):\n        if self._conan_output_level <= LEVEL_DEBUG:\n            self._write_message(msg)\n        return self\n\n    def verbose(self, msg, fg=None, bg=None):\n        if self._conan_output_level <= LEVEL_VERBOSE:\n            self._write_message(msg, fg=fg, bg=bg)\n        return self\n\n    def status(self, msg, fg=None, bg=None):\n        if self._conan_output_level <= LEVEL_STATUS:\n            self._write_message(msg, fg=fg, bg=bg)\n        return self\n\n    # Remove in a later refactor of all the output.info calls\n    info = status\n\n    def title(self, msg):\n        if self._conan_output_level <= LEVEL_NOTICE:\n            self._write_message(\"\\n======== {} ========\".format(msg),\n                                fg=Color.BRIGHT_MAGENTA)\n        return self\n\n    def subtitle(self, msg):\n        if self._conan_output_level <= LEVEL_NOTICE:\n            self._write_message(\"\\n-------- {} --------\".format(msg),\n                                fg=Color.BRIGHT_MAGENTA)\n        return self\n\n    def highlight(self, msg):\n        if self._conan_output_level <= LEVEL_NOTICE:\n            self._write_message(msg, fg=Color.BRIGHT_MAGENTA)\n        return self\n\n    def success(self, msg):\n        if self._conan_output_level <= LEVEL_NOTICE:\n            self._write_message(msg, fg=Color.BRIGHT_GREEN)\n        return self\n\n    def warning(self, msg, warn_tag=None):\n        if self._conan_output_level <= LEVEL_WARNING:\n            if warn_tag is not None and warn_tag in self._silent_warn_tags:\n                return self\n            warn_tag_msg = \"\" if warn_tag is None else f\"{warn_tag}: \"\n            self._write_message(f\"WARN: {warn_tag_msg}{msg}\", Color.YELLOW)\n        return self\n\n    def error(self, msg):\n        if self._conan_output_level <= LEVEL_ERROR:\n            self._write_message(\"ERROR: {}\".format(msg), Color.RED)\n        return self\n\n    def flush(self):\n        self.stream.flush()\n\n\ndef cli_out_write(data, fg=None, bg=None, endline=\"\\n\", indentation=0):\n    \"\"\"\n    Output to be used by formatters to dump information to stdout\n    \"\"\"\n\n    fg_ = fg or ''\n    bg_ = bg or ''\n    if (fg or bg) and color_enabled(sys.stdout):\n        data = f\"{' ' * indentation}{fg_}{bg_}{data}{Style.RESET_ALL}{endline}\"\n    else:\n        data = f\"{' ' * indentation}{data}{endline}\"\n\n    sys.stdout.write(data)\n", "path": "conan/api/output.py"}]}