From 4fe21f66991abeb1905e24c3bc3c634543d959a2 Mon Sep 17 00:00:00 2001
From: Delgan <delgan.py@gmail.com>
Date: Sun, 17 Jul 2022 09:18:56 +0200
Subject: [PATCH] Fix "repr()" tests failing on Python 3.11

---
 tests/test_repr.py | 87 +++++++++++++++++++---------------------------
 1 file changed, 36 insertions(+), 51 deletions(-)

--- a/tests/test_repr.py
+++ b/tests/test_repr.py
@@ -1,34 +1,11 @@
-import builtins
 import logging
 import pathlib
 import re
 import sys
-from inspect import iscoroutinefunction
 
-import loguru
 from loguru import logger
 
 
-class Wrapper:
-    def __init__(self, wrapped, *, repr, name):
-        self._wrapped = wrapped
-        self._repr = repr
-        self._name = name
-        self.raised = False
-
-    def __repr__(self):
-        return self._repr
-
-    def __getattr__(self, name):
-        if name == "__name__":
-            if self._name is None:
-                self.raised = True
-                raise AttributeError
-            else:
-                return self._name
-        return getattr(self._wrapped, name)
-
-
 def test_no_handler():
     assert repr(logger) == "<loguru.logger handlers=[]>"
 
@@ -112,22 +89,30 @@
     assert repr(logger) == "<loguru.logger handlers=[(id=0, level=10, sink=my_function)]>"
 
 
-def test_function_without_name(monkeypatch):
-    function = Wrapper(lambda _: None, repr="<FunctionWithout>", name=None)
-    monkeypatch.setattr(builtins, "callable", lambda x: x is function or callable(x))
+def test_callable_without_name():
+    class Function:
+        def __call__(self):
+            pass
+
+        def __repr__(self):
+            return "<FunctionWithout>"
 
-    logger.add(function)
+    logger.add(Function())
     assert repr(logger) == "<loguru.logger handlers=[(id=0, level=10, sink=<FunctionWithout>)]>"
-    assert function.raised
 
 
-def test_function_with_empty_name(monkeypatch):
-    function = Wrapper(lambda _: None, repr="<FunctionEmpty>", name="")
-    monkeypatch.setattr(builtins, "callable", lambda x: x is function or callable(x))
+def test_callable_with_empty_name():
+    class Function:
+        __name__ = ""
+
+        def __call__(self):
+            pass
+
+        def __repr__(self):
+            return "<FunctionEmpty>"
 
-    logger.add(function)
+    logger.add(Function())
     assert repr(logger) == "<loguru.logger handlers=[(id=0, level=10, sink=<FunctionEmpty>)]>"
-    assert not function.raised
 
 
 def test_coroutine_function():
@@ -138,32 +123,32 @@
     assert repr(logger) == "<loguru.logger handlers=[(id=0, level=10, sink=my_async_function)]>"
 
 
-def test_coroutine_function_without_name(monkeypatch):
-    async_function = Wrapper(lambda _: None, repr="<AsyncFunctionWithout>", name=None)
-    monkeypatch.setattr(
-        loguru._logger,
-        "iscoroutinefunction",
-        lambda x: x is async_function or iscoroutinefunction(x),
-    )
+def test_coroutine_callable_without_name():
+    class CoroutineFunction:
+        async def __call__(self):
+            pass
 
-    logger.add(async_function)
+        def __repr__(self):
+            return "<AsyncFunctionWithout>"
+
+    logger.add(CoroutineFunction())
     assert (
         repr(logger) == "<loguru.logger handlers=[(id=0, level=10, sink=<AsyncFunctionWithout>)]>"
     )
-    assert async_function.raised
 
 
-def test_coroutine_function_with_empty_name(monkeypatch):
-    async_function = Wrapper(lambda _: None, repr="<AsyncFunctionEmpty>", name="")
-    monkeypatch.setattr(
-        loguru._logger,
-        "iscoroutinefunction",
-        lambda x: x is async_function or iscoroutinefunction(x),
-    )
+def test_coroutine_function_with_empty_name():
+    class CoroutineFunction:
+        __name__ = ""
+
+        def __call__(self):
+            pass
+
+        def __repr__(self):
+            return "<AsyncFunctionEmpty>"
 
-    logger.add(async_function)
+    logger.add(CoroutineFunction())
     assert repr(logger) == "<loguru.logger handlers=[(id=0, level=10, sink=<AsyncFunctionEmpty>)]>"
-    assert not async_function.raised
 
 
 def test_standard_handler():
--- a/tests/test_filesink_rotation.py
+++ b/tests/test_filesink_rotation.py
@@ -49,8 +49,8 @@
                     return self._timestamp
                 return getattr(self._wrapped, name)
 
-        def patched_stat(filepath):
-            stat = __stat__(filepath)
+        def patched_stat(filepath, *args, **kwargs):
+            stat = __stat__(filepath, *args, **kwargs)
             wrapped = StatWrapper(stat, filesystem.get(os.path.abspath(filepath)))
             return wrapped
 
--- a/tests/test_interception.py
+++ b/tests/test_interception.py
@@ -1,4 +1,5 @@
 import logging
+import sys
 
 from loguru import logger
 
@@ -7,15 +8,15 @@
 
 class InterceptHandler(logging.Handler):
     def emit(self, record):
-        # Get corresponding Loguru level if it exists
+        # Get corresponding Loguru level if it exists.
         try:
             level = logger.level(record.levelname).name
         except ValueError:
             level = record.levelno
 
-        # Find caller from where originated the logged message
-        frame, depth = logging.currentframe(), 2
-        while frame.f_code.co_filename == logging.__file__:
+        # Find caller from where originated the logged message.
+        frame, depth = sys._getframe(6), 6
+        while frame and frame.f_code.co_filename == logging.__file__:
             frame = frame.f_back
             depth += 1
 
@@ -30,7 +31,7 @@
 
     expected = (
         "tests.test_interception - test_interception.py - test_formatting - DEBUG - "
-        "10 - 38 - test_interception - This is the message\n"
+        "10 - 39 - test_interception - This is the message\n"
     )
 
     with make_logging_logger("tests", InterceptHandler()) as logging_logger:
@@ -157,4 +158,4 @@
         logging.warning("ABC")
 
     result = writer.read()
-    assert result == "test_using_logging_function 157 test_interception test_interception.py ABC\n"
+    assert result == "test_using_logging_function 158 test_interception test_interception.py ABC\n"
