Delgan / loguru

Python logging made (stupidly) simple
MIT License
19.96k stars 699 forks source link

There is an exception problem when printing brace using f-string #1210

Open yuanlongliao opened 1 month ago

yuanlongliao commented 1 month ago
from loguru import logger
LOG_FORMAT = "{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {extra} | {message}"
logger.remove()
logger.add(sys.stdout, format=LOG_FORMAT)
logger.info(f"{'{'}", e = "extra1")

When a string with '{' or '}' characters is printed in f-string format and the extra parameter is included, the following exception will be thrown

exception:

Traceback (most recent call last):
  File "/home/unitx/unitx_repos/util/util/log_test.py", line 114, in <module>
    logger.info(f"{'{'}", e = "extra1")
  File "/home/unitx/miniconda3/envs/unified_dev/lib/python3.11/site-packages/loguru/_logger.py", line 2044, in info
    __self._log("INFO", False, __self._options, __message, args, kwargs)
  File "/home/unitx/miniconda3/envs/unified_dev/lib/python3.11/site-packages/loguru/_logger.py", line 2021, in _log
    log_record["message"] = message.format(*args, **kwargs)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: Single '{' encountered in format string

I have observed that other people have also encountered this problem before, may I ask whether this problem has been fixed? I switched to loguru from another library, so it's not practical to change it line by line

trim21 commented 1 month ago

this is expected and it's not caused by f-string

f"{'{'}" is just "{" and is not valid format string

trim21 commented 1 month ago

the final logging message is generated from message.format(*args, **kwrags), so if you pass any args or kwargs to log, message need to be valid format string, which means you need to use {{ as {, }} as } and { } must pair.

So you need to do this instead: logger.info(f"{'{{'}", e = "extra1")

yuanlongliao commented 1 month ago

This is indeed the case, but there is a more troublesome place is that in actual use, it is impossible to predict whether there is a '}' or '{' in the content that needs to be printed, and then use with f-string, and eventually there will be a similar situation: param = '11111111111111111111{2222222222222222222' logger.info(f"{param}", e = "extra1")

trim21 commented 1 month ago

This is indeed the case, but there is a more troublesome place is that in actual use, it is impossible to predict whether there is a '}' or '{' in the content that needs to be printed, and then use with f-string, and eventually there will be a similar situation: param = '11111111111111111111{2222222222222222222' logger.info(f"{param}", e = "extra1")

if you can't make sure param is valid format just don't use it as message, logger.info("some message", param=param, e = "extra1")

Delgan commented 1 month ago

I don't consider this as a bug per se, but I agree it's quite unfortunate.

Initially, keyword arguments were intended for formatting purposes only. Then they evolved to capture contextual variables added to the record as well.

I hadn't foreseen that these two uses would lead to inadvertent edge cases like this one. It was a design error.

Eventually, the automatic formatting from keyword arguments will be removed. However, it's not yet available, sorry.