Repository: Delgan/loguru
Pull request #575 (2022-01-24 04:38:11)

When serializing, preserve Unicode information

Hi, I'm here again, I resubmitted the pull request.

---------------

👇 Here is the original content：

I want to keep the original information of the Unicode code and not serialize it to ASCII

```python
In [2]: json.dumps({"中文":"你好"})
Out[2]: '{"\\u4e2d\\u6587": "\\u4f60\\u597d"}'

In [3]: json.dumps({"中文":"你好"},ensure_ascii=False)
Out[3]: '{"中文": "你好"}'
```


Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 907088f..c3bbe95 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -3,6 +3,7 @@
 
 - Modify coroutine sink to make it discard log messages when ``loop=None`` and no event loop is running (due to internally using ``asyncio.get_running_loop()`` in place of ``asyncio.get_event_loop()``).
 - Remove the possibility to add a coroutine sink with ``enqueue=True`` if ``loop=None`` and no event loop is running.
+- Prevent non-ascii characters to be escaped while logging JSON message with ``serialize=True`` (`#574 <https://github.com/Delgan/loguru/pull/575>`_, thanks `@ponponon <https://github.com/ponponon>`_).
 - Fix ``flake8`` errors and improve code readability (`#353 <https://github.com/Delgan/loguru/issues/353>`_, thanks `@AndrewYakimets <https://github.com/AndrewYakimets>`_).
 
 
diff --git a/loguru/_handler.py b/loguru/_handler.py
index a77b134..d12ef88 100644
--- a/loguru/_handler.py
+++ b/loguru/_handler.py
@@ -257,7 +257,7 @@ class Handler:
             },
         }
 
-        return json.dumps(serializable, default=str) + "\n"
+        return json.dumps(serializable, default=str, ensure_ascii=False) + "\n"
 
     def _queued_writer(self):
         message = None


Test patch:
diff --git a/tests/test_add_option_serialize.py b/tests/test_add_option_serialize.py
index 402d5f9..a635b3c 100644
--- a/tests/test_add_option_serialize.py
+++ b/tests/test_add_option_serialize.py
@@ -1,4 +1,5 @@
 import json
+import re
 import sys
 
 from loguru import logger
@@ -6,10 +7,12 @@ from loguru import logger
 
 class JsonSink:
     def __init__(self):
+        self.message = None
         self.dict = None
         self.json = None
 
     def write(self, message):
+        self.message = message
         self.dict = message.record
         self.json = json.loads(message)
 
@@ -23,6 +26,17 @@ def test_serialize():
     assert set(sink.dict.keys()) == set(sink.json["record"].keys())
 
 
+def test_serialize_non_ascii_characters():
+    sink = JsonSink()
+    logger.add(sink, format="{level.icon} {message}", serialize=True)
+    logger.debug("天")
+    assert re.search(r'"message": "([^\"]+)"', sink.message).group(1) == "天"
+    assert re.search(r'"text": "([^\"]+)"', sink.message).group(1) == "🐞 天\\n"
+    assert re.search(r'"icon": "([^\"]+)"', sink.message).group(1) == "🐞"
+    assert sink.json["text"] == "🐞 天\n"
+    assert sink.dict["message"] == sink.json["record"]["message"] == "天"
+
+
 def test_serialize_exception():
     sink = JsonSink()
     logger.add(sink, format="{message}", serialize=True, catch=False)
@@ -77,7 +91,7 @@ def test_serialize_exception_none_tuple():
     }
 
 
-def test_serialize_exception_instrance():
+def test_serialize_exception_instance():
     sink = JsonSink()
     logger.add(sink, format="{message}", serialize=True, catch=False)