prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Adding loguru compatiblity with pytest caplog
  ## Description
  `caplog` fixture in pytest captures the logging output for testing if appropriate warnings have been raised.
  
  By default pytest uses the standard `logging` module, but since we are using `loguru` appropriate patching needs to be added.
  
  ## Additional Context
  https://loguru.readthedocs.io/en/stable/resources/migration.html#making-things-work-with-pytest-and-caplog
  
  
  </issue>
  <code>
  [start of src/syft/logger.py]
  1 # stdlib
  2 import os
  3 from typing import Any
  4 from typing import Callable
  5 from typing import NoReturn
  6 from typing import TextIO
  7 from typing import Union
  8 
  9 # third party
  10 from loguru import logger
  11 
  12 LOG_FORMAT = "[{time}][{level}][{module}]][{process.id}] {message}"
  13 
  14 logger.remove()
  15 DEFAULT_SINK = "syft_{time}.log"
  16 
  17 
  18 def remove() -> None:
  19     logger.remove()
  20 
  21 
  22 def add(
  23     sink: Union[None, str, os.PathLike, TextIO] = None,
  24     level: str = "ERROR",
  25 ) -> None:
  26     sink = DEFAULT_SINK if sink is None else sink
  27     try:
  28         logger.add(
  29             sink=sink,
  30             format=LOG_FORMAT,
  31             enqueue=True,
  32             colorize=False,
  33             diagnose=True,
  34             backtrace=True,
  35             rotation="10 MB",
  36             retention="1 day",
  37             level=level,
  38         )
  39     except BaseException:
  40         logger.add(
  41             sink=sink,
  42             format=LOG_FORMAT,
  43             enqueue=True,
  44             colorize=False,
  45             diagnose=True,
  46             backtrace=True,
  47             level=level,
  48         )
  49 
  50 
  51 def traceback_and_raise(e: Any, verbose: bool = False) -> NoReturn:
  52     try:
  53         if verbose:
  54             logger.opt(lazy=True).exception(e)
  55         else:
  56             logger.opt(lazy=True).critical(e)
  57     except BaseException as ex:
  58         logger.debug("failed to print exception", ex)
  59     if not issubclass(type(e), Exception):
  60         e = Exception(e)
  61     raise e
  62 
  63 
  64 def create_log_and_print_function(level: str) -> Callable:
  65     def log_and_print(*args: Any, **kwargs: Any) -> None:
  66         try:
  67             method = getattr(logger.opt(lazy=True), level, None)
  68             if "print" in kwargs and kwargs["print"] is True:
  69                 del kwargs["print"]
  70                 print(*args, **kwargs)
  71                 if "end" in kwargs:
  72                     # clean up extra end for printing
  73                     del kwargs["end"]
  74 
  75             if method is not None:
  76                 method(*args, **kwargs)
  77             else:
  78                 raise Exception(f"no method {level} on logger")
  79         except BaseException as e:
  80             msg = f"failed to log exception. {e}"
  81             try:
  82                 logger.debug(msg)
  83             except Exception as e:
  84                 print(f"{msg}. {e}")
  85 
  86     return log_and_print
  87 
  88 
  89 def traceback(*args: Any, **kwargs: Any) -> None:
  90     return create_log_and_print_function(level="exception")(*args, **kwargs)
  91 
  92 
  93 def critical(*args: Any, **kwargs: Any) -> None:
  94     return create_log_and_print_function(level="critical")(*args, **kwargs)
  95 
  96 
  97 def error(*args: Any, **kwargs: Any) -> None:
  98     return create_log_and_print_function(level="error")(*args, **kwargs)
  99 
  100 
  101 def warning(*args: Any, **kwargs: Any) -> None:
  102     return create_log_and_print_function(level="warning")(*args, **kwargs)
  103 
  104 
  105 def info(*args: Any, **kwargs: Any) -> None:
  106     return create_log_and_print_function(level="info")(*args, **kwargs)
  107 
  108 
  109 def debug(*args: Any, **kwargs: Any) -> None:
  110     return create_log_and_print_function(level="debug")(*args, **kwargs)
  111 
  112 
  113 def trace(*args: Any, **kwargs: Any) -> None:
  114     return create_log_and_print_function(level="trace")(*args, **kwargs)
  115
  [end of src/syft/logger.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/src/syft/logger.py b/src/syft/logger.py
  --- a/src/syft/logger.py
  +++ b/src/syft/logger.py
  @@ -1,4 +1,5 @@
   # stdlib
  +import logging
   import os
   from typing import Any
   from typing import Callable
  @@ -20,7 +21,7 @@
   
   
   def add(
  -    sink: Union[None, str, os.PathLike, TextIO] = None,
  +    sink: Union[None, str, os.PathLike, TextIO, logging.Handler] = None,
       level: str = "ERROR",
   ) -> None:
       sink = DEFAULT_SINK if sink is None else sink
  @@ -40,7 +41,6 @@
           logger.add(
               sink=sink,
               format=LOG_FORMAT,
  -            enqueue=True,
               colorize=False,
               diagnose=True,
               backtrace=True,
  
verification_info: {"golden_diff": "diff --git a/src/syft/logger.py b/src/syft/logger.py\n--- a/src/syft/logger.py\n+++ b/src/syft/logger.py\n@@ -1,4 +1,5 @@\n # stdlib\n+import logging\n import os\n from typing import Any\n from typing import Callable\n@@ -20,7 +21,7 @@\n \n \n def add(\n-    sink: Union[None, str, os.PathLike, TextIO] = None,\n+    sink: Union[None, str, os.PathLike, TextIO, logging.Handler] = None,\n     level: str = \"ERROR\",\n ) -> None:\n     sink = DEFAULT_SINK if sink is None else sink\n@@ -40,7 +41,6 @@\n         logger.add(\n             sink=sink,\n             format=LOG_FORMAT,\n-            enqueue=True,\n             colorize=False,\n             diagnose=True,\n             backtrace=True,\n", "issue": "Adding loguru compatiblity with pytest caplog\n## Description\r\n`caplog` fixture in pytest captures the logging output for testing if appropriate warnings have been raised.\r\n\r\nBy default pytest uses the standard `logging` module, but since we are using `loguru` appropriate patching needs to be added.\r\n\r\n## Additional Context\r\nhttps://loguru.readthedocs.io/en/stable/resources/migration.html#making-things-work-with-pytest-and-caplog\r\n\n", "before_files": [{"content": "# stdlib\nimport os\nfrom typing import Any\nfrom typing import Callable\nfrom typing import NoReturn\nfrom typing import TextIO\nfrom typing import Union\n\n# third party\nfrom loguru import logger\n\nLOG_FORMAT = \"[{time}][{level}][{module}]][{process.id}] {message}\"\n\nlogger.remove()\nDEFAULT_SINK = \"syft_{time}.log\"\n\n\ndef remove() -> None:\n    logger.remove()\n\n\ndef add(\n    sink: Union[None, str, os.PathLike, TextIO] = None,\n    level: str = \"ERROR\",\n) -> None:\n    sink = DEFAULT_SINK if sink is None else sink\n    try:\n        logger.add(\n            sink=sink,\n            format=LOG_FORMAT,\n            enqueue=True,\n            colorize=False,\n            diagnose=True,\n            backtrace=True,\n            rotation=\"10 MB\",\n            retention=\"1 day\",\n            level=level,\n        )\n    except BaseException:\n        logger.add(\n            sink=sink,\n            format=LOG_FORMAT,\n            enqueue=True,\n            colorize=False,\n            diagnose=True,\n            backtrace=True,\n            level=level,\n        )\n\n\ndef traceback_and_raise(e: Any, verbose: bool = False) -> NoReturn:\n    try:\n        if verbose:\n            logger.opt(lazy=True).exception(e)\n        else:\n            logger.opt(lazy=True).critical(e)\n    except BaseException as ex:\n        logger.debug(\"failed to print exception\", ex)\n    if not issubclass(type(e), Exception):\n        e = Exception(e)\n    raise e\n\n\ndef create_log_and_print_function(level: str) -> Callable:\n    def log_and_print(*args: Any, **kwargs: Any) -> None:\n        try:\n            method = getattr(logger.opt(lazy=True), level, None)\n            if \"print\" in kwargs and kwargs[\"print\"] is True:\n                del kwargs[\"print\"]\n                print(*args, **kwargs)\n                if \"end\" in kwargs:\n                    # clean up extra end for printing\n                    del kwargs[\"end\"]\n\n            if method is not None:\n                method(*args, **kwargs)\n            else:\n                raise Exception(f\"no method {level} on logger\")\n        except BaseException as e:\n            msg = f\"failed to log exception. {e}\"\n            try:\n                logger.debug(msg)\n            except Exception as e:\n                print(f\"{msg}. {e}\")\n\n    return log_and_print\n\n\ndef traceback(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"exception\")(*args, **kwargs)\n\n\ndef critical(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"critical\")(*args, **kwargs)\n\n\ndef error(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"error\")(*args, **kwargs)\n\n\ndef warning(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"warning\")(*args, **kwargs)\n\n\ndef info(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"info\")(*args, **kwargs)\n\n\ndef debug(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"debug\")(*args, **kwargs)\n\n\ndef trace(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"trace\")(*args, **kwargs)\n", "path": "src/syft/logger.py"}]}